<div dir="ltr"><div class="gmail_extra">Hi Evgenii,</div><div class="gmail_extra"><br></div><div class="gmail_extra">Thanks for working on this. We could really use a better approach.</div><div class="gmail_extra"><br></div><div class="gmail_extra"><span style="font-size:12.8px">> To ensure ABI stability, libc++ attempts to tightly control the set of </span><span style="font-size:12.8px">symbols exported from libc++.so. </span></div><div class="gmail_extra"><br></div><div class="gmail_extra">I think this is a simplification (but correct me if I'm wrong). libc++ can manage the symbols exported</div><div class="gmail_extra">from libc++.so only using __attribute__((visibility("hidden"))). __always_inline__ is used to try and prevent</div><div class="gmail_extra">symbols from being emitted in user code, not libc++.so.</div><div class="gmail_extra"><br></div><div class="gmail_extra">> At -O0 optimization level indiscriminate inlining results in very</div>> large stack frames. As a consequence, removing these attributes<div><div class="gmail_extra">> speeds up libc++ test suite by 10%. </div><div class="gmail_extra"><br></div><div class="gmail_extra">This has always bothered me. I wonder if always-inline also</div><div class="gmail_extra">messes with tooling which expect the code was compiled at "-O0".</div><div class="gmail_extra">I'm thinking of gcov as an example.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Evgenii, I have some questions:</div><div class="gmail_extra"><br></div><div class="gmail_extra">1. What would happen if the user attempts to take the address of a function marked</div><div class="gmail_extra">`__attribute__((internal_linkage))`? Wouldn't this case required external linkage?</div><div class="gmail_extra">For libc++ it's sufficient if it causes a compile error because users aren't allowed</div><div class="gmail_extra">to take the address of functions in the standard library.</div><div class="gmail_extra"><br></div><div class="gmail_extra">2. It would be great if we could apply the attribute to a namespace, that in turn applies it to</div><div class="gmail_extra">   all of the symbols within. Would this be possible? </div><div class="gmail_extra"><br></div><div class="gmail_extra">/Eric</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><span style="font-size:12.8px"><br></span><div class="gmail_quote">On Thu, Oct 15, 2015 at 6:37 PM, Evgenii Stepanov <span dir="ltr"><<a href="mailto:eugeni.stepanov@gmail.com" target="_blank">eugeni.stepanov@gmail.com</a>></span> wrote:<br><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">Hi,<br>
<br>
this is a proposal to add a new function attribute to Clang. The<br>
attribute would be called "internal_linkage" (or any other name) and<br>
it would, as the name implies, set the function linkage to "internal".<br>
<br>
The attribute would let us apply the same behavior as of C "static"<br>
keyword, but on C++ class methods. AFAIK, there is no way to do this<br>
currently.<br>
<br>
The first use case would be libc++.<br>
<br>
To ensure ABI stability, libc++ attempts to tightly control the set of<br>
symbols exported from libc++.so.  This is achieved with a "trick" of<br>
marking all functions and class methods defined in the library headers<br>
on Linux/MacOSX with::<br>
<br>
  __attribute__((always_inline, visibility("hidden")))<br>
<br>
All direct calls to functions marked with the always_inline attribute<br>
are inlined and are never emitted as an external symbol<br>
reference. Hidden visibility removes the symbol from the shared<br>
library exports list.<br>
<br>
This approach has a number of drawbacks.<br>
<br>
* always_inline functions are not always inlined. Inlining is an<br>
  optimization, and there are multiple cases when a compiler can<br>
  decide against it.<br>
<br>
  * Clang can sometimes emit an **unreachable**<br>
    call to an always_inline function as an external symbol reference.<br>
  * Inlining may be impossible between functions with incompatible<br>
    attributes. For example, ``__attribute__((no_sanitize_address))``,<br>
    which suppresses AddressSanitizer instrumentation in a function,<br>
    prevents inlining of functions that do not have the same<br>
    attribute.<br>
<br>
* At -O0 optimization level indiscriminate inlining results in very<br>
  large stack frames. As a consequence, removing these attributes<br>
  speeds up libc++ test suite by 10%.<br>
<br>
In this case, what libc++ really needs is internal linkage. Inlining<br>
is just an undesired side effect. The always_inline attribute could be<br>
replaced with the proposed internal_linkage attribute for all the<br>
benefits and no drawbacks.<br>
</blockquote></div><br></div></div></div>