[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