r218141 - In the Itanium ABI, move stuff to the comdat of variables with static init.

Reid Kleckner rnk at google.com
Wed Dec 17 15:51:21 PST 2014


On Wed, Dec 17, 2014 at 3:06 PM, Richard Smith <richard at metafoo.co.uk>
wrote:
>
> On Wed, Dec 17, 2014 at 1:32 PM, Richard Smith <richard at metafoo.co.uk>
> wrote:
>
>> On Wed, Dec 17, 2014 at 12:48 PM, Reid Kleckner <rnk at google.com> wrote:
>>
>>> Are we sure this is correct? In the motivating example, what if 'f' gets
>>> inlined? Then 'g' will have the code of 'f' embedded into it, but it will
>>> not be part of the comdat that statically initializes the guard variable.
>>>
>>> struct S {
>>>   static const int x;
>>> };
>>> // const int S::x = 42;
>>> inline const int *f() {
>>>   static const int y = S::x;
>>>   return &y;
>>> }
>>> const int *g() { return f(); }
>>>
>>> I spent a coffee break a few weeks ago worrying about this, and we came
>>> to the conclusion that we can't do this if we want to support inlining from
>>> a comdat. Maybe it's illegal for LLVM to inline f from a comdat, but that's
>>> pretty sad.
>>>
>>
>> It is. Do we have any alternative that supports inlining and the above
>> testcase?
>>
>
> (Summarizing offline discussion)
>
> While evaluating the initializer for a static local variable, we can track
> whether the initialization depends on any properties that might not hold in
> another translation unit. If it does, then we should assume that the
> variable may have dynamic initialization in another TU. In that case:
>
>  - generate a guard variable that is initialized to the "already
> initialized" state.
>  - generate code to initialize the variable within the local function
> (just copy across the constant value).
>

If you do this, you should remove the ODR bit from the linkage of the guard
variable. It no longer has a functionally equivalent definition across TUs.


> This removes any need to put the inline function into a COMDAT with the
> static local variable. (We still need to put the local variable and its
> guard variable in a COMDAT together, though.)
>
>
> Separately, it seems that LLVM should not inline across COMDAT boundaries,
> unless it somehow knows that every definition of the COMDAT will provide an
> equivalent definition of the symbol (for instance, because it's got an
> *_odr linkage), and likewise for other optimizations that transfer
> information between globals. A strong definition in a COMDAT should behave
> similarly to a weak definition.
>

Based on talking to David, we think the frontend should be responsible for
picking whether things are ODR or not, and then LLVM optimizations can
continue to be mostly ignorant of comdats. For example, the D5 destructor
comdat group functions should all be inlinable.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141217/1143bf27/attachment.html>


More information about the cfe-commits mailing list