[LLVMdev] Selectively Disable Inlining for Functions

Chris Lattner sabre at nondot.org
Tue Mar 7 10:59:12 PST 2006

On Tue, 7 Mar 2006, Markus F.X.J. Oberhumer wrote:
>> I'm currently working with an experimental analysis pass that checks for 
>> calls to memory allocation functions; inlining and dead code elimination 
>> might make the pass more stable, but we don't want to inline the calls to 
>> the memory allocation functions until after our analysis pass is finished.
> Back in May 2005 Chris had firmly rejected supporting "noinline" (see mailing 
> list thread "calling conventions and inlining"), so I've written an 
> implementation for our private LLVM branch. Please see the attached patch.
> If this patch now seems acceptable for integration into the main CVS I can 
> also provide you the corresponding patch for llvm-gcc.

Hi Markus, please don't take any of these comments about your patch as 
disrespect: I can tell you worked hard on it, and it is nice work. 
Hopefully my previous email helps clarify my position about why I think 
these sorts of things are dangerous, and the ideas below will crystalize a 
way forward.

Here are the specific problems with your patch that I see:

1. ExplicitInline/ImplicitInline are currently ignored.  These fall into
    the class of dangerous information that is hard to use in a
    meaningful way.  For example just becase a method is defined in the
    body of a class, it doesn't tell you anything about its potential for
    inlining: huge methods can be there too.  I think that using this
    information is extremely dangerous.
2. Using "always inline" is also dangerous, as described in my previous
    mail.  However, as a compromise, the new front-end DOES inline "always
    inline" functions itself, which should provide this capability in a way
    that is compatible with GCC.  In particular, relying on this allows
    us to honor "always inline" within a file, without honoring it across
    files.  In addition these functions will be inlined before any other
    optimization is performed (a good thing for these).
3. As implemented, your 'never inline' option has a significant problem:
    it does not disable IPO of the function.  In particular, one reason
    that people want to disable inlining is so that there is a well-known
    entry-point to the function.  If the function isn't inlined, but
    arguments are deleted, this capability breaks.

As a specific proposal to provide "never inline" in a way that is 
low-impact on LLVM and solves #3, I suggest that we add a new 
llvm.neverinline global array variable (like the llvm.used global).  This 
global would point to all neverinline functions, and would have appending 
linkage (like llvm.used).

With this design, these functions would be assumed to be used externally 
(because a global with external visibility points to them) so no IPO could 
modify their arguments, and no assumptions about the callers could be 
made.  Because the global has appending linkage, the standard LLVM linker 
will correctly concatenate the list of functions to not inline when it 
links LLVM modules.

Finally, the inliner would be taught to look for this global, and refuse 
to inline anything pointed to by it.

By using a global like this, no changes to the .ll,.bc, or in-memory 
format would be required, and no passes need to be modified to update 
these attributes as they create and clone functions.

Does this seem like a reasonable approach?  Who wants to implement it? :)



More information about the llvm-dev mailing list