[cfe-dev] [RFC] __attribute__((internal_linkage))

Eric Fiselier via cfe-dev cfe-dev at lists.llvm.org
Thu Oct 15 18:55:29 PDT 2015


Hi Evgenii,

Thanks for working on this. We could really use a better approach.

> To ensure ABI stability, libc++ attempts to tightly control the set of symbols
exported from libc++.so.

I think this is a simplification (but correct me if I'm wrong). libc++ can
manage the symbols exported
from libc++.so only using __attribute__((visibility("hidden"))).
__always_inline__ is used to try and prevent
symbols from being emitted in user code, not libc++.so.

> At -O0 optimization level indiscriminate inlining results in very
> large stack frames. As a consequence, removing these attributes
> speeds up libc++ test suite by 10%.

This has always bothered me. I wonder if always-inline also
messes with tooling which expect the code was compiled at "-O0".
I'm thinking of gcov as an example.

Evgenii, I have some questions:

1. What would happen if the user attempts to take the address of a function
marked
`__attribute__((internal_linkage))`? Wouldn't this case required external
linkage?
For libc++ it's sufficient if it causes a compile error because users
aren't allowed
to take the address of functions in the standard library.

2. It would be great if we could apply the attribute to a namespace, that
in turn applies it to
   all of the symbols within. Would this be possible?

/Eric



On Thu, Oct 15, 2015 at 6:37 PM, Evgenii Stepanov <eugeni.stepanov at gmail.com
> wrote:

> Hi,
>
> this is a proposal to add a new function attribute to Clang. The
> attribute would be called "internal_linkage" (or any other name) and
> it would, as the name implies, set the function linkage to "internal".
>
> The attribute would let us apply the same behavior as of C "static"
> keyword, but on C++ class methods. AFAIK, there is no way to do this
> currently.
>
> The first use case would be libc++.
>
> To ensure ABI stability, libc++ attempts to tightly control the set of
> symbols exported from libc++.so.  This is achieved with a "trick" of
> marking all functions and class methods defined in the library headers
> on Linux/MacOSX with::
>
>   __attribute__((always_inline, visibility("hidden")))
>
> All direct calls to functions marked with the always_inline attribute
> are inlined and are never emitted as an external symbol
> reference. Hidden visibility removes the symbol from the shared
> library exports list.
>
> This approach has a number of drawbacks.
>
> * always_inline functions are not always inlined. Inlining is an
>   optimization, and there are multiple cases when a compiler can
>   decide against it.
>
>   * Clang can sometimes emit an **unreachable**
>     call to an always_inline function as an external symbol reference.
>   * Inlining may be impossible between functions with incompatible
>     attributes. For example, ``__attribute__((no_sanitize_address))``,
>     which suppresses AddressSanitizer instrumentation in a function,
>     prevents inlining of functions that do not have the same
>     attribute.
>
> * At -O0 optimization level indiscriminate inlining results in very
>   large stack frames. As a consequence, removing these attributes
>   speeds up libc++ test suite by 10%.
>
> In this case, what libc++ really needs is internal linkage. Inlining
> is just an undesired side effect. The always_inline attribute could be
> replaced with the proposed internal_linkage attribute for all the
> benefits and no drawbacks.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151015/43b3b779/attachment.html>


More information about the cfe-dev mailing list