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? :)
-Chris
--
http://nondot.org/sabre/
http://llvm.org/