public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jeff Law <law@redhat.com>
To: "H.J. Lu" <hjl.tools@gmail.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: Problem with static const objects and LTO
Date: Wed, 16 Sep 2020 11:41:27 -0600	[thread overview]
Message-ID: <9f71c1a6-5bec-00ae-d6cf-48815a78af78@redhat.com> (raw)
In-Reply-To: <CAMe9rOqRYmzOG8OgtvcmRAWYH2vEe3g0PEzWYtnya_ZS624K9g@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4492 bytes --]


On 9/16/20 11:32 AM, H.J. Lu wrote:
> On Wed, Sep 16, 2020 at 10:24 AM Jeff Law <law@redhat.com> wrote:
>>
>> On 9/16/20 11:13 AM, H.J. Lu wrote:
>>> On Wed, Sep 16, 2020 at 10:10 AM Jeff Law <law@redhat.com> wrote:
>>>> On 9/16/20 11:05 AM, H.J. Lu wrote:
>>>>> On Wed, Sep 16, 2020 at 9:53 AM Jeff Law via Gcc-patches
>>>>> <gcc-patches@gcc.gnu.org> wrote:
>>>>>> Consider a TU with file scoped "static const object utf8_sb_map".   A
>>>>>> routine within the TU will stuff &utf8_sb_map into an object, something
>>>>>> like:
>>>>>>
>>>>>> fu (...)
>>>>>>
>>>>>> {
>>>>>>
>>>>>>   if (cond)
>>>>>>
>>>>>>     dfa->sb_char = utf8_sb_map;
>>>>>>
>>>>>>   else
>>>>>>
>>>>>>     dfa->sb_char = malloc (...);
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> There is another routine in the TU which looks like
>>>>>>
>>>>>> bar (...)
>>>>>>
>>>>>> {
>>>>>>
>>>>>>   if (dfa->sb_char != utf8_sb_map)
>>>>>>
>>>>>>     free (dfa->sb_char);
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> Now imagine that the TU is compiled (with LTO) into a static library,
>>>>>> libgl.a and there's a DSO (libdso.so) which gets linked against libgl.a
>>>>>> and references the first routine (fu).  We get a copy of fu in the DSO
>>>>>> along with a copy of utf8_sb_map.
>>>>>>
>>>>>>
>>>>>> Then imagine there's a main executable that dynamicly links against
>>>>>> libdso.so, then links statically against libgl.a.  Assume the  main
>>>>>> executable does not directly reference fu(), but does call a routine in
>>>>>> libdso.so which eventually calls fu().  Also assume the main executable
>>>>>> directly calls bar().  Again, remember we're compiling with LTO, so we
>>>>>> don't suck in the entire TU, just the routines/data we need.
>>>>>>
>>>>>>
>>>>>> In this scenario, both libdso.so and the main executable are going to a
>>>>>> copy of utf8_sb_map and they'll be at different addresses.  So when the
>>>>>> main executable calls into libdso.so which in turn calls libdso's copy
>>>>>> of fu() which stuffs the address of utf8_sb_map from the DSO into
>>>>>> dfa->sb_char.  Later the main executable calls bar() that's in the main
>>>>>> executable.  It does the comparison to see if dfa->sb_char is equal to
>>>>>> utf8_sb_map -- but it's using the main executable's copy of utf8_sb_map
>>>>>> and naturally free() blows us because it was passed a static object, not
>>>>>> a malloc'd object.
>>>>>>
>>>>>>
>>>>>> ISTM this is a lot like the problem we have where we inline functions
>>>>>> with static data.   To fix those we use STB_GNU_UNIQUE.  But I don't see
>>>>>> any code in the C front-end which would utilize STB_GNU_UNIQUE.  It's
>>>>>> support seems limited to C++.
>>>>>>
>>>>>>
>>>>>> How is this supposed to work for C?
>>>>>>
>>>>>>
>>>>>> Jeff
>>>>>>
>>>>>>
>>>>> Can you group utf8_sb_map, fu and bar together so that they are defined
>>>>> together?
>>>> They're all defined within the same TU in gnulib.  It's the LTO
>>>> dead/unreachable code elimination that results in just parts of the TU
>>>> being copied into the DSO and a different set copied into the main
>>>> executable.  In many ways LTO makes this look a lot like the static data
>>>> member problems we've had to deal with in the C++ world.
>>> In this case, LTO should treat them as in a single group.   Removing
>>> one group member should remove the whole group.  Keep one member
>>> should keep the whole group.
>> Do you mean ensure they're all in a partition together?  I think that
>> might work in the immediate term, but is probably brittle in the long
>> term.  I'd tend to lean towards forcing these static data objects to be
>> STB_GNU_UNIQUE -- that seems more robust to me.
> Isn't STB_GNU_UNIQUE binding global?  How does it work with
>
> static const int foo;
>
> and
>
> static const double foo;
>
> in different files?

It's global in the sense that it uniqifies across TU boundaries, which
is its purpose.  Consider a function scoped static object in a template
or C++ inlined function.  We can end up with multiple copies in
different TUs and we have to collapse them to a single representative
object.  We'd need to do the same thing here.  Without thinking a whole
lot about it, but ISTM that if LTO pulls in a function that references a
static object, then that static object would need to be STB_GNU_UNIQUE.


For something like you've shown above, I'd *hope* we give an ODR error :-)


Jeff


[-- Attachment #2: pEpkey.asc --]
[-- Type: application/pgp-keys, Size: 1763 bytes --]

  reply	other threads:[~2020-09-16 17:41 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-16 16:51 Jeff Law
2020-09-16 17:05 ` H.J. Lu
2020-09-16 17:10   ` Jeff Law
2020-09-16 17:13     ` H.J. Lu
2020-09-16 17:24       ` Jeff Law
2020-09-16 17:32         ` H.J. Lu
2020-09-16 17:41           ` Jeff Law [this message]
2020-09-16 17:52 ` Joseph Myers
2020-09-16 20:24   ` Jeff Law
2020-09-17  7:04     ` Richard Biener
2020-09-17 18:18       ` Jeff Law
2020-09-17 19:03         ` Jakub Jelinek
2020-10-07 22:08           ` Jeff Law
2020-10-07 22:09             ` Jeff Law
2020-10-07 23:12               ` H.J. Lu
2020-10-07 23:16                 ` Jeff Law
2020-10-09 18:36                 ` Jeff Law

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9f71c1a6-5bec-00ae-d6cf-48815a78af78@redhat.com \
    --to=law@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hjl.tools@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).