<div dir="ltr">> <span style="font-size:12.800000190734863px">From looking at the code, it seems like LLVM is basically opting MachO into -fvisibility-inlines-hidden all the time, i.e. if the function is linkonce, it's discardable, so mark it hidden to pretend the compiler inlined it and discarded it. However, this isn't conforming, because the addresses of inline functions will no longer compare equal across DSOs.</span><div><span style="font-size:12.800000190734863px"><br></span></div><div><span style="font-size:12.800000190734863px">I think there is a nuance, it is marking these as "auto-hide": it just means that the address is not taken in the current compilation unit IIRC.</span></div><div><span style="font-size:12.800000190734863px">The linker decides that it can hide it in the DSO if none of the compilation unit is using the address based on this auto-hide flag.</span></div><div><br></div><div>Does it make sense?</div><div><div><span style="font-size:12.800000190734863px">-- </span></div></div><div><span style="font-size:12.800000190734863px">Mehdi</span></div><div><span style="font-size:12.800000190734863px"><br></span></div></div><div class="gmail_extra"><br><div class="gmail_quote">2018-02-07 11:27 GMT-08:00 Reid Kleckner via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">From looking at the code, it seems like LLVM is basically opting MachO into -fvisibility-inlines-hidden all the time, i.e. if the function is linkonce, it's discardable, so mark it hidden to pretend the compiler inlined it and discarded it. However, this isn't conforming, because the addresses of inline functions will no longer compare equal across DSOs.<div><br></div><div>Realistically, nobody cares about this guarantee. Maybe we should enable -fvisibility-inlines-hidden by default to resolve this inconsistency between the platforms. It's a much better out of the box experience anyway.</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 7, 2018 at 11:11 AM, Steven Wu <span dir="ltr"><<a href="mailto:stevenwu@apple.com" target="_blank">stevenwu@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space">That is a good question and I don't know. The optimization is defined include/llvm/Analysis/<wbr>ObjectUtils.h. If I enable that for weak_odr + unnamed_addr, no tests are failing so I guess it is a safe optimization? :)<div><br></div><div>It is probably because the autohide optimization is targeted at c++ templates and inline functions and we know they have linkonce_odr linkage, which suggests whoever uses this symbol should have their own copy. Because the linkonce_odr is safe to drop so it is safe to assume that nothing else should be relying on the symbol to be available from the current linkage unit, so it is safe to hide from symbol table. weak_odr is often used to force to compiler and linker to provide the implementation for template instantiation that is not available in the header. I don't think they are safe to drop in all cases. </div><span class="m_9051214914006251206HOEnZb"><font color="#888888"><div><br></div></font></span><div><span class="m_9051214914006251206HOEnZb"><font color="#888888">Steven</font></span><div><div class="m_9051214914006251206h5"><br><div><div><div><div><div><br><blockquote type="cite"><div>On Feb 7, 2018, at 10:29 AM, Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>> wrote:</div><br class="m_9051214914006251206m_-6083759929176628110Apple-interchange-newline"><div><div dir="ltr">There should be no semantic difference between linkonce_odr and weak_odr, except that weak_odr is non-discardable. Why doesn't the autohide optimization work just as well on weak_odr + unnamed_addr as linkonce_odr + unnamed_addr?</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 6, 2018 at 5:35 PM, Steven Wu via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I recently found that thinLTO doesn't deal with globals that has linkonce_odr and unnamed_addr (for macho at least) because it prohibits the autohide optimization during link time.<br>
<br>
In LLVM, we tagged a global linkonce_odr and unnamed_addr to indicate to the linker can hide them from symbol table if they were picked (aka, linkonce_odr_auto_hide linkage). It is very commonly used for some type of Tables for c++ code in clang for example.<br>
However, thinLTO is promoting these symbols to weak_odr + unnamed_addr, which lose the property. As a result, it introduces unnecessary weak external symbols and weak external are not good for performance on darwin platforms.<br>
<br>
I have few proposed solutions for this issue but I don't know which one works the best for none macho platforms and other LTO clients like lld.<br>
<br>
1. Use llvm.compiler_used.<br>
As far as I know, the linkage promote are just there to keep the symbol through internalize and codegen so adding them to compiler used should solve this issue. I was told that there was some objections to do that in the first place. Is it because the globals added to compiler used is ignored by the optimizer so they cannot be internalized and they cannot be optimized away? This works well for the case I am looking at because c++ VTable can't really be optimized and for darwin platforms because we can rely on ld64 to do dead_stripping if needed.<br>
<br>
2. Add visibility hidden when promote linkonce_odr + unnamed_addr.<br>
Well,this doesn't really preserve the link semantics, but neither does promoting linkonce_odr to weak_odr. The global will still end up in the symbol table but at least it isn't external so it doesn't come with a performance cost.<br>
<br>
3. We can teach function importer that it cannot just reference to linkonce_odr + unnamed_addr symbols without importing them. I have some thoughts about how to do this so I can propose something if people are interested going down this route. I am expecting at least add an entry in the global summery and change the cost of importing symbols that references to linkonce_odr + unnamed_addr symbols.<br>
<br>
4. As a temporary fix, just targeting at the VTables for c++. We can put a special case for global constants that uses this linkage so they are never promoted and their parents are never imported into other modules. The benefit for inlining global constants is very minimal and I don't think we are doing it currently.<br>
<br>
Let me know if any of those solutions work for other LTO client.<br>
<br>
Thanks<br>
<br>
Steven<br>
______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
</blockquote></div><br></div>
</div></blockquote></div><br></div></div></div></div></div></div></div></div></blockquote></div><br></div>
</div></div><br>______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div>