[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.
-
Devang
More information about the cfe-dev
mailing list