[llvm-dev] [RFC] AlwaysInline codegen

David Blaikie via llvm-dev llvm-dev at lists.llvm.org
Thu Aug 20 18:04:53 PDT 2015


On Thu, Aug 20, 2015 at 5:53 PM, Richard Smith <richard at metafoo.co.uk>
wrote:

> On Thu, Aug 20, 2015 at 5:36 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>>
>>
>> On Thu, Aug 20, 2015 at 5:19 PM, Evgenii Stepanov via llvm-dev <
>> llvm-dev at lists.llvm.org> wrote:
>>
>>> Hi,
>>>
>>> There is a problem with the handling of alwaysinline functions in
>>> Clang: they are not always inlined. AFAIK, this may only happen when
>>> the caller is in the dead code, but then we don't always successfully
>>> remove all dead code.
>>>
>>> Because of this, we may end up emitting an undefined reference
>>
>>
>> Why would the failure to inline produced an undefined reference? Wouldn't
>> we just keep the body around?
>>
>
> No, if it's available_externally we'll discard it before we emit code.
>
>
>> The following example seems to demonstrate this
>>
>> void f1();
>> inline __attribute__((always_inline)) void f2() {
>>
>> Try:
>
> extern inline __attribute__((gnu_inline, always_inline)) void f2() {
>

Ah, thanks - I didn't know that was possible in C++. I knew that the weird
C inline semantics had such a thing.

Good(ish) to know. Thanks!

>   f1();
>> }
>> void (*f3())() {
>>   return f2;
>> }
>>
>>
>>
>>> for an
>>> "inline __attribute__((always_inline))" function. Libc++ relies on the
>>> compiler never doing that - it has lots of functions in the headers
>>> marked this way and does _not_ export them from libc++.so.
>>>
>>> Current implementation in clang emits alwaysinline+inline functions as
>>> available_externally definitions.
>>
>>
>> I heard this mentioned in another thread - and I'm not seeing that
>> behavior. Is there an extra step missing necessary to produce that behavior?
>>
>
> You need to first arrange a situation where you'd get an
> available_externally definition without the always_inline.
>

>
>> The inliner is an SCC pass, and as
>>> such it does not process unreachable functions at all. This means that
>>> AlwaysInliner may leave some alwaysinline functions not inlined. If
>>> such function has an available_externally linkage, it is not emitted
>>> into the binary, and all calls to it are emitted as undefined symbol
>>> references.
>>>
>>> Some time ago I've made an attempt to add a DCE pass before the
>>> AlwaysInliner pass to fix this. Thst
>>>  (a) caused a big churn in the existing tests
>>>  (b) must be done at -O0 as well, which is probably undesirable and
>>> could inflate compilation time
>>>  (c) feels like patching over a bigger problem.
>>>
>>> The following, better, idea was suggested by Chandler Carruth and
>>> Richard Smith.
>>>
>>> Instead of emitting an available_externally definition for an
>>> alwaysinline function, we emit a pair of
>>>  1. internal alwaysinline definition (let's call it F.inlinefunction -
>>> it demangles nicely)
>>>  2a. A stub F() { musttail call F.inlinefunction }
>>>   -- or --
>>>  2b. A declaration of F.
>>>
>>> The frontend ensures that F.inlinefunction is only used for direct
>>> calls, and the stub is used for everything else (taking the address of
>>> the function, really). Declaration (2b) is emitted in the case when
>>> "inline" is meant for inlining only (like __gnu_inline__ and some
>>> other cases).
>>>
>>> This way has a number of useful properties that are easy to enforce.
>>> 1. alwaysinline functions are always internal
>>> 2. AlwaysInliner can be split from normal inliner; it would be a super
>>> simple implementation that would ensure that there are no alwaysinline
>>> functions remaining after it's done.
>>> 3. alwaysinline functions must never reach backend and can be rejected
>>> before machine code generation (in SelectionDAG?).
>>>
>>> As this changes the semantics of alwaysinline attribute in the IR, we
>>> would need to reserve a new attribute ID, rename the current ID to
>>> legacy_alwaysinline or something similar and only enforce the above
>>> properties on the new attribute.
>>>
>>> There is a proposed Clang patch here: http://reviews.llvm.org/D12087
>>> The patch only implements the Clang codegen part of the proposal and
>>> does not do any of the backend improvements.
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> llvm-dev at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150820/2e200e19/attachment.html>


More information about the llvm-dev mailing list