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

Duncan P. N. Exon Smith via llvm-dev llvm-dev at lists.llvm.org
Tue Jul 12 18:52:28 PDT 2016


The status quo isn't "linkonce_odr + visibility_hidden".  The status quo is "linkonce_odr + visibility_hidden + always_inline".  I guess you're suggesting removing the always_inline?

I believe the "always_inline" is protecting against some objects being built separately from (and with a slightly different libc++ than) others, which is common in the case of static archives.  Using "internal" gives the same protection.

Aside from address-taken functions (where the address of functions will depend on the translation unit, instead of causing a link error), I think "internal" is a strict improvement over the status quo.  Changing to "linkonce_odr + hidden" would be more fragile, although a possible tradeoff for some vendors.

Even with internal linkage, the linker will have the opportunity to de-duplicate the functions if they are optimized the same way.

> On 2016-Jul-12, at 18:38, Mehdi Amini via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> Hi Evgenii,
> 
> I have one question about this (planned) change: what if a function is not inlined? The linker will not ODR merge them with this change, which isn’t great.
> 
> What makes “internal” linkage more desirable than "linkonce_odr + visibility hidden"?
> 
>> Mehdi
> 
> 
>> On Jul 12, 2016, at 6:16 PM, Evgenii Stepanov via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>> 
>> Hi,
>> 
>> it's been put on hold for other higher priority work. I still want to
>> get it done one day, but it's not clear when that would be.
>> 
>> On Tue, Jul 12, 2016 at 6:11 PM, Akira Hatanaka <ahatanak at gmail.com> wrote:
>>> Hi Evgenii,
>>> 
>>> I was wondering what the status is of your work to attach "internal_linkage"
>>> to methods of standard library classes in libc++. The following piece of
>>> code doesn't link because a symbol (string::empty) is undefined and it
>>> sounds like your work might fix the linkage error I'm seeing.
>>> 
>>> $ cat test1.cpp
>>> #include <string>
>>> #include <functional>
>>> 
>>> int main() {
>>> using namespace std::placeholders;
>>> auto b = std::bind(&std::string::empty, _1);
>>> }
>>> 
>>> On Mon, Nov 9, 2015 at 1:58 PM, Evgenii Stepanov via llvm-dev
>>> <llvm-dev at lists.llvm.org> wrote:
>>>> 
>>>> In fact, during the code review we've decided against allowing this
>>>> attribute on namespaces: http://reviews.llvEm.org/D13925
>>>> 
>>>> 
>>>> The intended use of this attribute in libc++ is on functions that
>>>> programs are not allowed to take address of, like all methods of
>>>> standard library classes. Visibility("hidden") attribute (which we are
>>>> replacing with internal_linkage) violates ODR the same way.
>>>> 
>>>> Also, this attribute (for us) is not about locality or performance.
>>>> Its primary purpose is to reliably exclude a class method from the
>>>> export table. This is the way libc++ manages ABI stability: all class
>>>> methods that are not part of the library ABI are defined in the
>>>> headers with a set of attributes that ensure that they become internal
>>>> to the translation unit. Always_inline does that in almost all cases,
>>>> but almost is not good enough. Internal_linkage is a straighforward
>>>> way to achieve the same.
>>>> 
>>>> 
>>>> On Mon, Nov 9, 2015 at 1:34 PM, Martin J. O'Riordan
>>>> <martin.oriordan at movidius.com> wrote:
>>>>> With respect only to '__attribute__((internal_linkage))', not 'nodebug'
>>>>> and other parts of this topic; does hiding "some" members and not others not
>>>>> introduce a violation of the ODR because some members of the class as it
>>>>> appears in one translation unit are not the same actual definitions as the
>>>>> apparently "same" members of the class in another translation unit?  In
>>>>> particular the ODR requirement that would ensure that the address of a
>>>>> method was the same regardless of where the address was taken, including
>>>>> 'static' methods (no 'this' pointer)?  Or hidden things like the guard
>>>>> variables for local static objects, default argument initialisers (which are
>>>>> instanced), etc.?
>>>>> 
>>>>> I must admit that having spent years trying to lock down the definition
>>>>> of the ODR, that this seems to fly in the opposite direction of the intent
>>>>> of that rule.
>>>>> 
>>>>> I can (sort of) see why for particular reasons of locality you might
>>>>> want multiple actual definitions, even though they might exhibit the same
>>>>> behaviour, but maybe the answer for locality optimisation would be for the
>>>>> linker technology to evolve so that multiple copies of the same definition
>>>>> (sic) could be made; perhaps even at the Basic Block level [Block Level
>>>>> Linking].  But this too would lie under the auspices of the "as if" rule and
>>>>> respect the ODR.
>>>>> 
>>>>> There is something I am missing in this that is not making me at all
>>>>> comfortable about the use of this attribute for namespaces (apart from the
>>>>> reopening issues raised by others), and in particular the application to
>>>>> parts of a class but not the whole class.  I just feel that this is leading
>>>>> to semantic trouble.
>>>>> 
>>>>> Thanks,
>>>>> 
>>>>>       MartinO
>>>>> 
>>>>> -----Original Message-----
>>>>> From: Evgenii Stepanov [mailto:eugeni.stepanov at gmail.com]
>>>>> Sent: 09 November 2015 18:49
>>>>> To: Robinson, Paul <Paul_Robinson at playstation.sony.com>
>>>>> Cc: Chris Lattner <clattner at apple.com>;
>>>>> sstewartgallus00 at mylangara.bc.ca; llvm-dev at lists.llvm.org; Martin J.
>>>>> O'Riordan <martin.oriordan at movidius.com>
>>>>> Subject: Re: [llvm-dev] [cfe-dev] [RFC]
>>>>> __attribute__((internal_linkage))
>>>>> 
>>>>> Sorry, I totally missed updates to this thread.
>>>>> 
>>>>> Anonymous namespace does not work for libc++ because we need to hide
>>>>> some class members, and export the rest. Namespace would hide all of them.
>>>>> AFAIK, "static" is un-deprecated in C++11 for multiple reasons, including
>>>>> this one.
>>>>> 
>>>>> I agree that nodebug should not affect codegen. It would also kill debug
>>>>> info (ex. all debug locations in libc++ headers).
>>>>> 
>>>>> 
>>>>> On Mon, Nov 2, 2015 at 11:57 AM, Robinson, Paul via llvm-dev
>>>>> <llvm-dev at lists.llvm.org> wrote:
>>>>>> 
>>>>>> 
>>>>>>> -----Original Message-----
>>>>>>> From: llvm-dev [mailto:llvm-dev-bounces at lists.llvm.org] On Behalf Of
>>>>>>> Chris Lattner via llvm-dev
>>>>>>> Sent: Saturday, October 31, 2015 2:58 PM
>>>>>>> To: sstewartgallus00 at mylangara.bc.ca
>>>>>>> Cc: LLVM Developers
>>>>>>> Subject: Re: [llvm-dev] [cfe-dev] [RFC]
>>>>>>> __attribute__((internal_linkage))
>>>>>>> 
>>>>>>> Hi Stewart,
>>>>>>> 
>>>>>>> I saw this get brought up at the LLVM devmtg in the context of
>>>>>>> improving the stack size of libc++ frames.
>>>>>>> 
>>>>>>> Have you guys considered a different approach to solving this
>>>>>>> problem?  In the case of libc++, the _LIBCPP_INLINE_VISIBILITY macro
>>>>>>> currently expands out to "__attribute__ ((__always_inline__))”.  It
>>>>>>> seems reasonable to me to have it also add the “nodebug” attribute as
>>>>>>> well.  This should allow the allocas generated by inlining lots of
>>>>>>> frames to be promoted to registers (because there is no debug info to
>>>>>>> pessimize).
>>>>>> 
>>>>>> Are you suggesting that 'nodebug' should affect code generation?
>>>>>> It most definitely should not...
>>>>>> --paulr
>>>>>> 
>>>>>>> 
>>>>>>> This would dramatically shrink the stack frames of code using libc++
>>>>>>> at - O0, and would also make it go a lot faster.
>>>>>>> 
>>>>>>> -Chris
>>>>>>> 
>>>>>>> 
>>>>>>>> On Oct 29, 2015, at 6:35 AM, Martin J. O'Riordan via llvm-dev
>>>>>>>> <llvm-
>>>>>>> dev at lists.llvm.org> wrote:
>>>>>>>> 
>>>>>>>> I haven't been able to figure out from this thread why this
>>>>>>>> attribute is
>>>>>>> necessary at all.
>>>>>>>> 
>>>>>>>> Anonymous or unnamed namespaces were added to C++ for this very
>>>>>>>> purpose,
>>>>>>> but the ISO C++ Standard does not discuss "linkage" per-se because it
>>>>>>> is outside the scope of the language specification.  But it does
>>>>>>> describes it in terms of having a hidden name which is "unique" to
>>>>>>> the translation unit, and under the "as if" rule, internal linkage is
>>>>>>> a common convention for achieving this.
>>>>>>>> 
>>>>>>>> This is just Standardese for dealing with what compiler
>>>>>>>> implementers
>>>>>>> typically handle as "internal linkage" anyway; at the same time, the
>>>>>>> use of 'static' for this purpose was deprecated.  This is
>>>>>>> specifically stated in C++98 section 7.3.1.1 and unnamed namespaces
>>>>>>> are still similarly defined in C++17 (Working Paper) although the
>>>>>>> specific reference to the deprecation of 'static' for this purpose is
>>>>>>> now gone.
>>>>>>>> 
>>>>>>>> The closest the Standard gets to talking about linkage is with
>>>>>>>> Linkage
>>>>>>> Specifications, and even here it tries to avoid to avoid treading on
>>>>>>> the definitions things like internal versus external linkage.
>>>>>>>> 
>>>>>>>> So I am curious, what does this proposed attribute on namespaces
>>>>>>>> achieve
>>>>>>> that cannot already be achieved with an anonymous or unnamed
>>>>>>> namespace?
>>>>>>>> 
>>>>>>>> Thanks,
>>>>>>>> 
>>>>>>>>   Martin O'Riordan - Movidius Ltd.
>>>>>>>> 
>>>>>>>> -----Original Message-----
>>>>>>>> From: cfe-dev [mailto:cfe-dev-bounces at lists.llvm.org] On Behalf Of
>>>>>>> Evgenii Stepanov via cfe-dev
>>>>>>>> Sent: 23 October 2015 22:41
>>>>>>>> To: Steven Stewart-Gallus <sstewartgallus00 at mylangara.bc.ca>
>>>>>>>> Cc: Clang Dev <cfe-dev at lists.llvm.org>
>>>>>>>> Subject: Re: [cfe-dev] [RFC] __attribute__((internal_linkage))
>>>>>>>> 
>>>>>>>> Sounds right. The proposed attribute is a rough equivalent of
>>>>>>>> 
>>>>>>>> static void foo::do_method(void)
>>>>>>>> {
>>>>>>>> // implementation here
>>>>>>>> }
>>>>>>>> 
>>>>>>>> where "static" does not mean a static class member, but makes the
>>>>>>> declaration local to the translation unit. C-style "static".
>>>>>>>> 
>>>>>>>> The patch in http://reviews.llvm.org/D13925 (waiting for review,
>>>>>>>> btw!)
>>>>>>> supports this attribute on classes and namespaces, with this syntax:
>>>>>>>> 
>>>>>>>> namespace __attribute__((internal_linkage)) { }
>>>>>>>> 
>>>>>>>> 
>>>>>>>> On Fri, Oct 23, 2015 at 9:03 AM, Steven Stewart-Gallus via cfe-dev
>>>>>>>> <cfe-
>>>>>>> dev at lists.llvm.org> wrote:
>>>>>>>>> Hello,
>>>>>>>>> 
>>>>>>>>> Can I ask for some clarification?
>>>>>>>>> 
>>>>>>>>> Apparently, C++ doesn't allow to static class methods?
>>>>>>>>> 
>>>>>>>>> While in C one might write inside a header file:
>>>>>>>>> 
>>>>>>>>> static inline void mylib_foo_do_method(struct mylib_foo *foo) {
>>>>>>>>> // implementation here
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> In C++ the typical style would be to write something like:
>>>>>>>>> 
>>>>>>>>> namespace mylib {
>>>>>>>>> 
>>>>>>>>> void foo::do_method(void)
>>>>>>>>> {
>>>>>>>>> // implementation here
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> Unfortunately, the C++ case then implies some linkage behaviour
>>>>>>>>> that some might not want.
>>>>>>>>> 
>>>>>>>>> Apparently, one can't do things like:
>>>>>>>>> 
>>>>>>>>> namespace mylib {
>>>>>>>>> 
>>>>>>>>> static void foo::do_method(void)
>>>>>>>>> {
>>>>>>>>> // implementation here
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> Or,
>>>>>>>>> 
>>>>>>>>> namespace {
>>>>>>>>> namespace mylib {
>>>>>>>>> 
>>>>>>>>> static void foo::do_method(void)
>>>>>>>>> {
>>>>>>>>> // implementation here
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> Also, if you wanted to an attribute to a whole namespace you
>>>>>>>>> should do something like the following I think:
>>>>>>>>> 
>>>>>>>>> namespace mylib {
>>>>>>>>> [[clang::internal_linkage]];
>>>>>>>>> 
>>>>>>>>> static void foo::do_method(void)
>>>>>>>>> {
>>>>>>>>> // implementation here
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Thank you,
>>>>>>>>> Steven Stewart-Gallus
>>>>>>>>> _______________________________________________
>>>>>>>>> cfe-dev mailing list
>>>>>>>>> cfe-dev at lists.llvm.org
>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>>>>>> _______________________________________________
>>>>>>>> cfe-dev mailing list
>>>>>>>> cfe-dev at lists.llvm.org
>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>>>>>> 
>>>>>>>> _______________________________________________
>>>>>>>> LLVM Developers mailing list
>>>>>>>> llvm-dev at lists.llvm.org
>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>>>> 
>>>>>>> _______________________________________________
>>>>>>> LLVM Developers mailing list
>>>>>>> llvm-dev at lists.llvm.org
>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>>> _______________________________________________
>>>>>> LLVM Developers mailing list
>>>>>> llvm-dev at lists.llvm.org
>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>> 
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> llvm-dev at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>> 
>>> 
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> 
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list