John McCall via llvm-dev
2016-Mar-11 19:13 UTC
[llvm-dev] RFC: A new ABI for virtual calls, and a change to the virtual call representation in the IR
> On Mar 11, 2016, at 9:56 AM, Reid Kleckner <rnk at google.com> wrote: > > On Fri, Mar 11, 2016 at 9:41 AM, John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote: > Okay, so, it sounds to me like LLVM basically treats strong definitions as protected, then. Should we just formalize that? > > I guess the proposal here would be: > 1. Remove protected visibility from LLVM. (Or deprecate it as equivalent to default.) > 2. Teach the ELF emitter to emit non-hidden strong definitions using ELF protected visibility. > 3. Teach the ELF emitter to emit non-hidden weak definitions using ELF default visibility (unless they’re unnamed_addr?). > > LLVM definitely thinks that strong definitions are "ODR", so we could do 2. I'm sure it would break somebody, somewhere though. We probably don't want to do 1 and 3, so that users can still mark their weak definitions as protected if they want to.Ah, that’s true, protected would still be meaningful for weak definitions.> GCC must do *some* inlining between strong definitions. Do you know what their rule is? Is it just a C++ thing? > > GCC only inlines strong definitions when -fPIC is disabled, meaning the code will be linked into the main executable. In this case, no interposition can occur because dynamic symbol search always starts in the executable. They also have -fno-semantic-interposition, which allows inlining strong definitions: > https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Optimize-Options.html#index-fsemantic-interposition-972 <https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Optimize-Options.html#index-fsemantic-interposition-972>Okay. The way we should be thinking about this is that -fno-semantic-interposition is the default rule on Clang. Now, if we fully embrace that by making symbols protected by default, we will break somebody out there who’s relying on interposition despite our poor support for it. Therefore, we need to have a story for how to unbreak them. For a small number of interposable symbols, it’s reasonable for us to tell them to use __attribute__((weak)). However, some people might have a ton of symbols they interpose, and other people will complain about us doing things differently from GCC; for those people, we will need to support an explicit -fsemantic-interposition option. So let’s talk about how to support that. Deciding whether a symbol is dynamically replaceable should not be a target- and option-specific decision in LLVM IR. It seems obvious to me that the right default rule is that symbols cannot be replaced. We already have several ways to express replaceability in IR, but they’re all linkage kinds, not visibility kinds; and in fact, there are some basic APIs in LLVM that assume that this decision is wholly a matter of the linkage kind. So it seems reasonable to me to eliminate protected visibility, and then make sure we can still express everything we need to using linkage, adding new linkage kinds as necessary. It seems to me that the basic breakdown here is: - Is this definition strong, ODR-weak, or semantically replaceable within the linkage unit? - Is this definition strong, ODR-weak, or semantically replaceable outside the linkage unit? When the definition uses the same rules for both, the existing linkages are fine: external, weak_odr / linkonce_odr, or weak, respectively. So let’s break down the cases by their declared visibility and see where it’s possible to use different rules inside and outside the linkage unit. Hidden definitions obviously never use different rules outside the linkage unit. Protected definitions are strong outside the linkage unit. If the definition isn’t strong within the linkage unit, this is a difference we don’t have the ability to express in linkage today. Default definitions under -fno-semantic-interposition use the same rules outside and inside the linkage unit. Default definitions under -fsemantic-interposition are semantically replaceable outside the linkage unit. The GCC rule is (thankfully) that the ODR still takes priority for inline definitions, and weak definitions are semantically replaceable everywhere, so this only actually makes a difference for strong definitions. We can’t just say that the definition is weak, because that changes linker behavior: we still want the linker to diagnose attempts to provide multiple strong definitions, and the strong definition still needs to take priority over any weak definitions within the linkage unit. So we don’t have the ability to express “strong internally, weak externally” today in linkage. Now, there are a number of things about linkage that are kindof orthogonal, and it would be nice to model them more orthogonally. That would be a major change in representation, though. Absent the will to do that, I propose that we: - remove/deprecate protected visibility, making visibility purely a hidden vs. non-hidden flag - add weak_for_linker, weak_odr_for_linker, linkonce_for_linker, and linkonce_odr_for_linker (better names highly desired) to model the weak-with-protected-visibility cases - add strong_for_linker (better name highly desired) to model the strong-but-interposable case John. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160311/7d24ed3e/attachment.html>
Rafael Espíndola via llvm-dev
2016-Mar-11 19:26 UTC
[llvm-dev] RFC: A new ABI for virtual calls, and a change to the virtual call representation in the IR
> Now, there are a number of things about linkage that are kindof orthogonal, > and it would be nice to model them more orthogonally. That would be a major > change in representation, though. Absent the will to do that, I propose > that we: > - remove/deprecate protected visibility, making visibility purely a hidden > vs. non-hidden flagThis would prevent us from propagating __attribute__((visibility("protected")) to a STV_PROTECTED in the .o, so I don't think we should do it.> - add weak_for_linker, weak_odr_for_linker, linkonce_for_linker, and > linkonce_odr_for_linker (better names highly desired) to model the > weak-with-protected-visibility cases > - add strong_for_linker (better name highly desired) to model the > strong-but-interposable caseFor representing interposition we would only need one extra linkage type: interposable (runtime_weak?). We could split the linkage into multiple orthogonal bits, like: odr, weak_for_linker, weak_for_runtime, can_be_dropped_if_unused, etc, but I think that is an independent cleanup Cheers, Rafael
John McCall via llvm-dev
2016-Mar-11 19:58 UTC
[llvm-dev] RFC: A new ABI for virtual calls, and a change to the virtual call representation in the IR
> On Mar 11, 2016, at 11:26 AM, Rafael Espíndola <rafael.espindola at gmail.com> wrote: >> Now, there are a number of things about linkage that are kindof orthogonal, >> and it would be nice to model them more orthogonally. That would be a major >> change in representation, though. Absent the will to do that, I propose >> that we: >> - remove/deprecate protected visibility, making visibility purely a hidden >> vs. non-hidden flag > > This would prevent us from propagating > __attribute__((visibility("protected")) to a STV_PROTECTED in the .o, > so I don't think we should do it.The whole point of this proposal is to get us to a state where we can use STV_PROTECTED for ordinary external or weak_for_linker symbols. __attribute__((visibility(“protected”))) on a strong definition would just map to ordinary non-hidden external linkage, which the backend would turn into STV_PROTECTED. __attribute__((visibility(“default”))) on a strong definition would map the same way unless -fsemantic-interposition was enabled. The point of removing protected visibility is that we don’t actually honor default visibility in the ELF sense, so it’s silly to pretend that LLVM visibility is the same as ELF visibility. ELF protected visibility is basically the semantics LLVM already assigns to default visibility.>> - add weak_for_linker, weak_odr_for_linker, linkonce_for_linker, and >> linkonce_odr_for_linker (better names highly desired) to model the >> weak-with-protected-visibility cases >> - add strong_for_linker (better name highly desired) to model the >> strong-but-interposable case > > For representing interposition we would only need one extra linkage > type: interposable (runtime_weak?).The other linkages are an attempt to preserve the ability to use STV_PROTECTED on weak definitions while eliminating protected visibility from LLVM.> We could split the linkage into multiple orthogonal bits, like: odr, weak_for_linker, > weak_for_runtime, can_be_dropped_if_unused, etc, but I think that is > an independent cleanupI agree that that would be best done independently. John.
Reasonably Related Threads
- RFC: A new ABI for virtual calls, and a change to the virtual call representation in the IR
- RFC: A new ABI for virtual calls, and a change to the virtual call representation in the IR
- RFC: A new ABI for virtual calls, and a change to the virtual call representation in the IR
- RFC: A new ABI for virtual calls, and a change to the virtual call representation in the IR
- RFC: Add an "interposible" linkage type (and implement -fsemantic-interposition)