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?