[PATCH] D97446: Change some addUsedGlobal to addUsedOrCompilerUsedGlobal

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 13 13:57:38 PST 2022


rjmccall added a comment.

I can understand how we got here, but it's a bad place to have ended up.

Toolchains that do dead-stripping need a way to prevent it for specific objects and functions.  Windows and Darwin toolchains have historically done aggressive dead-stripping in both the compiler and linker, so they've always had this need.  ELF toolchains have historically emitted code and restricted the linker in ways that, together, largely inhibit link-time dead-stripping (except of specific things like C++ entities with vague linkage).  As a result, ELF has gotten away with not providing a fine-grained way to prevent link-time dead-stripping for a long time, when otherwise that would have been a major blocker.

There are basically three broad categories of reasons why programs need to use features like this:

1. Some system at runtime needs to be able to find the entity "reflectively" (generally, because it's in a section with a special name or will be looked up by its symbol name).  Usually this is intended as a kind of passive global registration, and so dead-stripping needs to be completely blocked for the entity.
2. Some system at runtime that finds the entity "reflectively" will access it in weird ways that the compiler can't hope to understand.  The attribute is not being used to prevent dead-stripping (unless the entity is *also* a passive registration), but to block compiler analysis and optimization if the value *does* end up being used.  This tends to be a language-implementation thing more than something that a library would do.
3. The entity isn't actually unreferenced, but some portion of the toolchain is just unable to see that.  The most important example of this is a reference from inline assembly.

If I were a GCC developer reacting to the addition of `retain` to ELF, I would have given `__attribute__((used))` the stronger semantics, forcing the entity to be retained at link-time, and I would have introduced a weaker attribute (or attributes) that people could use selectively in the second and third cases if they wanted better dead-stripping.  To me, that's conservatively living up to user expectations about what they're trying to achieve with `__attribute__((used))` while giving them an opportunity to be more precise if it's useful; and it also unifies the semantics across object formats now that it's possible to do so.  But that's not generally how GCC developers do things; they tend to treat the current compiler behavior as an inviolate contract down to a very low level, and if you want different behavior, you need to use different options.  I can understand and sympathize with that approach, even if I think it also tends to create situations like this one.

At the end of the day, I don't think we have much choice but to follow GCC's lead on ELF platforms.  They get to define what these attributes mean, and if they want to make weaker guarantees on ELF, that's their decision.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97446/new/

https://reviews.llvm.org/D97446



More information about the cfe-commits mailing list