[LLVMdev] Proposal : Function Notes

Dan Gohman gohman at apple.com
Mon Aug 25 13:12:30 PDT 2008


Hi Devang,

I have a few questions below.

On Aug 22, 2008, at 4:40 PM, Devang Patel wrote:

> 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.

 From this description, it sounds like this particular problem is that
users just aren't accustomed to passing their "optimization" options
to the compiler during the "link" phase. Is there more to it than that?
Otherwise, this sounds like a problem best solved in documentation
and IDEs.

>
> 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.

We already have attributes like "noreturn". Can you discuss what the
main advantages are of using this new notes mechanism instead of just
adding more function attributes like the ones we already have?

>
>
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> // 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.

Would unsupported notes be rejected in the Verifier?

>
> 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().

Can the names directly correspond with the current -mattr names
somehow? It'd be good to avoid inventing yet another subtarget  
minilanguage :-).

>
> 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.

What's the fundamental difference between -Os and -O4 here? Why is one
appropriate for a note and the other not?

Also, if you're going to put -ffast-math in a note, please include in
this proposal a description of what happens when a -ffast-math function
is inlined into a -fno-fast-math function, or a -fno-fast-math function
is inlined into an -ffast-math one. Also, how about all the various
individual options that -ffast-math is an umbrella for?

Thanks,

Dan





More information about the llvm-dev mailing list