[cfe-dev] always_inline and noinline attributes

Matthijs Kooijman matthijs at stdin.nl
Wed Jul 23 15:10:44 PDT 2008

Hi Devang,

>> 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.
With plain gcc I assume? Or also clang and/or llvm-gcc?

This would suggest that gcc uses option 2) instead of option 1) and we should
probably too.

> 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.
Even if it did know, it wouldn't change anything as long as b.c didn't have
the function body. During LTO, the optimizer will know if we keep the
always_inline attribute in the IR (which corresponds to b) below and which we
should do IMO).

>> 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.
Yeah, but I was talking about a static function (which is identical to
internal and thus not exported, right?)

>> 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.

> I think, Option b) is easier to implement.
My guess was that throwing away the always_inline attribute and leaving the
linker unchanged would be easier, though it doesn't really matter much.

>> 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.

I was thinking of doing this stripping in the tool generating the LLVM module,
so opt (or perhaps clang?). It should always be able to just throw away the
always_inline global and the function should then be just a normal function.

I'm not sure if having such a strip-always_inline option is needed, at least
not if the default is to preserve always_inline information. I was proposing
this option, because IIRC someone proposed or implied throwing away the
always_inline info by default.

Devang, if I see this right, you agree with me that the combination of 2) and
b) are the "right" ones?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20080724/897347bb/attachment.sig>

More information about the cfe-dev mailing list