[cfe-dev] always_inline and noinline attributes

Devang Patel dpatel at apple.com
Wed Jul 23 10:21:54 PDT 2008

On Jul 23, 2008, at 4:43 AM, Matthijs Kooijman wrote:

> Hi all,
> I think that a lot of confusion arises from unclarity about what  
> always_inline
> actually means.
> The gcc docs [1] say:
> 	Generally, functions are not inlined unless optimization is  
> specified. For
> 	functions declared inline, this attribute inlines the function even  
> if no
> 	optimization level was specified.
> This is not very specific on topics on taking function pointers and  
> different
> translation units, though. I see roughtly two options:
> 1) A function marked always_inline must always be inlined. This  
> means it
> cannot be used in other way, so taking the address of an always_inline
> function is an error.

> 2) A function marked always_inline must be inlined whenever  
> possible. This
> means that any other uses simply won't get inlined, but are allowed.

Consider this example,
--- a.c ---
int foo() __attribute__((always_inline));
int foo() { return 42; }
int bar() {
	return foo() + foo();
--- b.c ---
extern int foo();
int main() {
	int (*fp)() = &foo;
	printf("%d\n", fp());
	return 0;

This works.

While compiling and optimizing b.c, the compiler does not know that  
foo() is marked as always_inline. However, during LTO, the optimizer  
will know.

> Neither of these options would actually limit the visibility of  
> thefunction,
> as far as I can see. When the function is static, the function can  
> normally be
> DCE'd after inlining (which will always happen for 1), but might not  
> happen
> for 2)).

In  case of 1) if a library exports always_inline function then it can  
not be DCE'd while building library.
> We could make always_inline work only with static functions, but I  
> can't
> really see why that would be necessary. IMHO, it would even greatly  
> reduce the
> usefulness of always_inline.
> When the function is not static, it will still be inlined at all the  
> callsites
> within the same translation unit. We then have again two  
> interpretations:
> a) An always_inline attribute only works within the same translation  
> unit.
> Functions that are visible outside of the unit, are treated just as  
> any other
> function at link time, as if the always_inline attribute was not  
> specified.

> b) An always_inline attribute stays with a function, regardless of its
> visibility. Any call site of the function, regardless of the  
> translation unit
> in which it lives, is inlined.
> Option a) would be easiest to implement, but again lose a lost of  
> usefulness
> compared to option b). Option b) does require that inlining happens  
> again at
> link time, so any call sites in other translation units are inlined  
> as well.

I think, Option b) is easier to implement.

> Also, option b) would be slightly tricky to combine with option 1),  
> unless the
> always_inline attribute is (can be) present on the definition as  
> well as the
> declaration of the function. Option b) combined with option 2)  
> shouldn't have
> this problem.
> I think that Chris is really in favour of option b) here, because  
> "inlining
> can sometimes change semantics". However, I still don't really  
> understand what
> kind of cases we are talking about. Chris, could you give an  
> example? Also, is
> this changing of semantics specific to always_inline? From what you  
> wrote, I
> would assume that this changing of semantics can happen with any  
> inline, so
> you shouldn't be doing any inlining at all at link time. Nor at  
> optimization
> time, for that matter, so I'm probably missing an essential point  
> here :-)
> Also, Devang pointed out that inlining at link time might not be  
> possible in
> all cases.

I did not mean this.

--- quote begin ---
>> At the very least, I would make it an option whether to strip the
>> always_inline info after compiling a single translation unit, so
>> people can
>> explicitely choose to still do (forced) inlining at link time.
> This may not be possible in all cases.
--- quote end ---

I meant, it may not be possible to guarantee that always_inline info  
is stripped in a llvm module presented to the link time optimizer.  
Sorry for the confusion.


More information about the cfe-dev mailing list