[LLVMdev] Proposal : Function Notes

Devang Patel dpatel at apple.com
Fri Aug 22 16:40:35 PDT 2008


Here is a proposal that I mentioned sometime ago. Any  
thoughts,comments or
suggestions on this proposal would be appreciated.
-
Devang

// 
= 
= 
=---------------------------------------------------------------------- 
===//
//                          Function Notes (or Traits)
// 
= 
= 
=---------------------------------------------------------------------- 
===//

This document describes the motivation and semantics of encoding  
function Notes
in the LLVM IR.

// 
= 
= 
=---------------------------------------------------------------------- 
===//
// The problem
//

Link Time Optimization

The llvm-gcc supports Link Time Optimization (LTO) at optimization  
level -O4 on
platforms where the linker support is available. This optimization  
level also
enables -O3 level optimization passes at the compile time. The -O3  
optimization
level enables aggressive inlining which may sacrifice code size for  
the code
performance. Now, the llvm-gcc also supports optimize for size, -Os.  
However,
right now there is not any way today to select optimize for size  
during link
time optimizations. At link time, the optimizer (LTO) may receive  
input LLVM
IR files that are compiled and optimized using various optimization  
choices.
Today, there is not any way to communicate these optimization choices  
to LTO,
which is a limitation.

Code Generation

The LLVM code generator supports various target specific choices, for  
example
optimizer for size, enable exception handling, eliminate frame pointer  
etc..
The llvm-gcc selects these choices based on the command line arguments  
and
default settings for the target. However, this information is not  
preserved in
llvm IR. This means, the llvm IR generated by llvm-gcc does not  
contain enough
information to independently reproduce llvm code generator behaviors  
using stand
alone tools like llc.

The Inliner

The GCC compiler supports inliner specific attributes, e.g. noinline,
always_inline. These attributes instruct the inliner to take special  
actions for
the function that specifies them. This information is not properly  
encoded in
LLVM IR, which means the llvm inliner is not informed about such special
requests, for example always_inline. Today, llvm-gcc respects GCC’s  
noinline
attribute but the current solution is not ideal.


// 
= 
= 
=---------------------------------------------------------------------- 
===//
// Proposed solution
//

The proposed solution to this problem to encode Function Notes in the  
IR.

define void @f()  notes("opt-size,pic,noinline") { ... }

Here, the notes include a comma separated list of strings. Note, the  
notes are
only attached to functions definitions. They are not attached to call  
or invoke
instructions. All supported notes must be documented in LLVM language  
reference.

The LLVM passes are responsible to take appropriate actions based on  
Function
Notes associated with function definition. For example,

define void @fn1()  notes("opt-size=1") { ... }

The function fn1() is being optimized for size without losing  
significant
performance. The inliner will update inlining threshold for fn1() such  
that the
functions called by fn1() are checked for size threshold for fn1()  
while being
inlined inside fn1(). If the function fn1() is itself inlined  
somewhere, for
example bar(), then the inlining threshold for bar() will be the  
deciding factor.

define void @fn2()  notes("opt-size=2") { ... }

The function fn2() is aggressively optimized for size. The code  
generator may
sacrifice performance while selecting instructions. The inliner will  
aggressively
reduce inlining threshold.

define void @fn3() notes("noinline") { ... }
define void @fn4() notes("always_inline") { ... }
define void @fn5() notes("noinline,always_inline") { ... }

Here the inliner is instructed to not inline function fn3() anywhere  
and inline
function fn4() everywhere. The function fn5() is malformed and it  
should be
rejected by the verifier.

define void @fn6()  notes("opt-size=1,noinline") { ... }

This is valid. The inliner is instructed to not inline fn6() here.

The target CPU specific features can be encoded as function notes.

define void @fn7() notes("x86.sse3") { ... }
define void @fn8() notes("x86.no-sse") { ... }
define void @fn9() notes("arm.no-thumb") { ... }
define void @fn10() notes("arm.force-thumb") { ... }

The fn7() note "sse3" instructs the x86 code generator to use SSE3  
instructions
in fn7() whereas the code generator should not use SSE instructions  
for function
fn8().

The Function Notes are not a place for all the llvm-gcc command line  
options.
Each note should represent function specific choice or an option for  
LLVM
passes. For example, optimize for size is appropriate because it  
instructions
the LLVM passes to make appropriate choices and update their  
thresholds. It is
appropriate to encode -ffast-math related choices here. It is not  
appropriate
to include -O4 as a function note.

// 
= 
= 
=---------------------------------------------------------------------- 
===//
// Implementation Overview
//

[0] Implement llvm::Function Note store and access interface.
[1] Update LLVM Asm Parser to recognize Function Notes.
[2] Update LLVM Printer to print Function Notes.
[3] Update LLVM BitCode Reader and Writer to handle Function Notes.
[4] Update optimization passes to recognize "opt-size" property
     Update the inliner to recognize "noinline" and "always_inline"  
Notes.
[5] Many code generation choices are encoded as global variables in
     TargetOptions.h. Update code generation passes to read these  
choices from
     function notes and eliminate these global variables.
[6] Update LTO to merge function Notes from various IR files  
appropriately.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080822/8aa9d2bf/attachment.html>


More information about the llvm-dev mailing list