[llvm-dev] ThinLTO and linkonce_odr + unnamed_addr

Steven Wu via llvm-dev llvm-dev at lists.llvm.org
Thu Feb 15 16:53:56 PST 2018


I explain that in the same thread to Peter.

I talked to Nick yesterday and It turns out to be an implementation choice. The overhead to deduplicate all the non-external symbols are too high so ld64 picks a subset that can potentially be beneficial, which are the "auto hide" symbols. So this is not a correctness issue but we might need a different heuristic for performance. 

Steven

> On Feb 15, 2018, at 4:45 PM, Rafael Avila de Espindola <rafael.espindola at gmail.com> wrote:
> 
> Steven Wu <stevenwu at apple.com <mailto:stevenwu at apple.com>> writes:
> 
>>> On Feb 15, 2018, at 4:16 PM, Rafael Avila de Espindola <rafael.espindola at gmail.com> wrote:
>>> 
>>> Steven Wu <stevenwu at apple.com> writes:
>>> 
>>>> I did a bit more digging for the auto hide problem. Here is my finding that prevent us from doing this by default in GlobalOpts
>>>> 
>>>> 1. When a symbol is linkonce_odr hidden unnamed_addr, it emits both '.private_extern' and '.weak_def_can_be_hidden' asm directives on macho platform. There result of that is .private_extern will win so this is essentially linkonce_odr hidden.
>>> 
>>> What do those directives mean? I assume .weak_def_can_be_hidden is the
>>> "you can drop this from the symbol table", but .private_extern I am not
>>> sure.
>> 
>> .private_extern is just suggesting the symbol has a hidden visibility with none local linkage type/
>> 
>>> 
>>>> 2. ld64 does treat these two type of symbols differently. For example, ld64 will deduplicate all the can_be_hidden symbols to reduce code size. This can't be achieved when the symbols is private external.
>>> 
>>> If I understand you correctly, ld64 will deduplicate
>>> std::vector<int>::push_back and std::vector<unsigned>::push_back, but it
>>> will not deduplicate std::vector<HiddenClassA>::push_back and
>>> std::vector<HiddenClassB>::push_back. Is that correct? Do you know why
>>> it has that limitation?
>> 
>> ld64 will dedup identical atoms regardless of names which helps in the case of templates with same underlying types.
> 
> Even if the symbols corresponding to the atoms are hidden? If so, why is
> having "linkonce_odr hidden unnamed_addr" causing problems?
> 
> To be clear, the testcase I have in mind is
> 
> #include <vector>
> struct __attribute__((visibility("hidden"))) Foo {};
> struct __attribute__((visibility("hidden"))) Bar {};
> void f1(std::vector<Foo> V, Foo X) {
>  V.push_back(X);
> }
> void f2(std::vector<Bar> V, Bar X) {
>  V.push_back(X);
> }
> 
> One ELF the symbols are hidden:
> 
> 0000000000000000   119 FUNC    WEAK   HIDDEN     8 _ZNSt6vectorI3BarSaIS0_EE9push_backERKS0_
> 0000000000000000   119 FUNC    WEAK   HIDDEN     5 _ZNSt6vectorI3FooSaIS0_EE9push_backERKS0_
> 
> and with lld's ICF I get:
> 
> /home/espindola/inst/clang/bin/ld.lld: selected .text._ZNSt6vectorI3FooSaIS0_EE9push_backERKS0_
> /home/espindola/inst/clang/bin/ld.lld:   removed .text._ZNSt6vectorI3BarSaIS0_EE9push_backERKS0_
> 
> Cheers,
> Rafael

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180215/8dea3a46/attachment.html>


More information about the llvm-dev mailing list