<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Mar 11, 2016, at 9:56 AM, Reid Kleckner <<a href="mailto:rnk@google.com" class="">rnk@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Fri, Mar 11, 2016 at 9:41 AM, John McCall <span dir="ltr" class=""><<a href="mailto:rjmccall@apple.com" target="_blank" class="">rjmccall@apple.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">Okay, so, it sounds to me like LLVM basically treats strong definitions as protected, then.  Should we just formalize that?</div><div class=""><br class=""></div><div class="">I guess the proposal here would be:</div><div class="">  1. Remove protected visibility from LLVM.  (Or deprecate it as equivalent to default.)</div><div class="">  2. Teach the ELF emitter to emit non-hidden strong definitions using ELF protected visibility.</div><div class="">  3. Teach the ELF emitter to emit non-hidden weak definitions using ELF default visibility (unless they’re unnamed_addr?).</div></div></blockquote><div class=""><br class=""></div><div class="">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.</div></div></div></div></div></blockquote><div><br class=""></div>Ah, that’s true, protected would still be meaningful for weak definitions.  </div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">GCC must do *some* inlining between strong definitions.  Do you know what their rule is?  Is it just a C++ thing?</div></div></blockquote><div class=""><br class=""></div><div class="">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:</div><div class=""><a href="https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Optimize-Options.html#index-fsemantic-interposition-972" class="">https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Optimize-Options.html#index-fsemantic-interposition-972</a><br class=""></div></div></div></div>
</div></blockquote></div><br class=""><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">It seems to me that the basic breakdown here is:</div><div class="">  - Is this definition strong, ODR-weak, or semantically replaceable within the linkage unit?</div><div class="">  - Is this definition strong, ODR-weak, or semantically replaceable outside the linkage unit?</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Hidden definitions obviously never use different rules outside the linkage unit.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Default definitions under -fno-semantic-interposition use the same rules outside and inside the linkage unit.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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:</div><div class="">  - remove/deprecate protected visibility, making visibility purely a hidden vs. non-hidden flag</div><div class="">  - 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</div><div class="">  - add strong_for_linker (better name highly desired) to model the strong-but-interposable case</div><div class=""><br class=""></div><div class="">John.</div></body></html>