<div dir="ltr">(best to include folks from previous conversations in threads - sometimes we can't all keep up to date with all the threads happening - so I've added John McCall here, and echristo since he might have some thoughts on this too)<br><br>I'd lean towards (1) too myself - give the LLVM constructs consistent semantics, and deal with the platform differences in the frontend during the mapping down to LLVM.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Feb 24, 2021 at 1:09 AM Fāng-ruì Sòng via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 2021-02-24, Fāng-ruì Sòng wrote:<br>
>Currently __attribute__((used)) lowers to llvm.used.<br>
><br>
>* On Mach-O, a GlobalObject in llvm.used gets the S_ATTR_NO_DEAD_STRIP<br>
>attribute, which prevents linker GC (dead stripping).<br>
>* On COFF, a non-local-linkage GlobalObject[1] in llvm.used gets the<br>
>/INCLUDE: linker option (similar to ELF `ld -u`), which prevents<br>
>linker GC.<br>
>  It should be possible to work with local linkage GlobalObject's as<br>
>well but that will require a complex COMDAT dance.<br>
>* On ELF, a global object llvm.used can be discarded by<br>
>ld.bfd/gold/ld.lld --gc-sections.<br>
>  (If the section is a C identifier name, __start_/__stop_ relocations<br>
>from a live input section can retain the section, even if its defined<br>
>symbols are not referenced. [2] .<br>
>  I understand that some folks use `__attribute__((used,<br>
>section("C_ident")))` and expect the sections to be similar to GC<br>
>roots, however,<br>
>  non-C-identifier cases are very common, too. They don't get<br>
>__start_/__stop_ linker magic and the sections can always be GCed.<br>
>  )<br>
><br>
>In LangRef, the description of llvm.used contains:<br>
><br>
>> If a symbol appears in the @llvm.used list, then the compiler, assembler, and **linker** are required to treat the symbol as if there is a reference to the symbol that it cannot see (which is why they have to be named). For example, if a variable has internal linkage and no references other than that from the @llvm.used list, it cannot be deleted. This is commonly used to represent references from inline asms and other things the compiler cannot “see”, and corresponds to “attribute((used))” in GNU C.<br>
><br>
>Note that the "linker" part does not match the reality on ELF targets.<br>
>It does match the reality on Mach-O and partially on COFF.<br>
><br>
>llvm.compiler.used:<br>
><br>
>> The @llvm.compiler.used directive is the same as the @llvm.used directive, except that it only prevents the compiler from touching the symbol. On targets that support it, this allows an **intelligent linker to optimize references to the symbol without being impeded** as it would be by @llvm.used.<br>
><br>
>Note that this explicitly mentions linker GC, so this appears to be<br>
>the closest thing to __attribute__((used)) on ELF.<br>
>However, LangRef also says:<br>
><br>
>> This is a rare construct that should only be used in rare circumstances, and should not be exposed to source languages.<br>
><br>
><br>
><br>
>My goal is to implement __attribute__((retain)) (which will be in GCC<br>
>11) on ELF. GCC folks think that 'used' and 'retain are orthogonal.<br>
>(see <a href="https://reviews.llvm.org/D96838#2578127" rel="noreferrer" target="_blank">https://reviews.llvm.org/D96838#2578127</a>)<br>
><br>
>Shall we<br>
><br>
>1. Lift the source language restriction on llvm.compiler.used and<br>
>change __attribute__((used)) to use llvm.compiler.used on ELF.<br>
<br>
It is too late here and I did not think of it clearly;-)<br>
<br>
Clarify:<br>
<br>
1. Lift the source language restriction on llvm.compiler.used, let llvm.used use SHF_GNU_RETAIN on ELF, and change __attribute__((used)) to use llvm.compiler.used on ELF.<br>
<br>
<br>
__attribute__((retain)) has semantics which are not described by<br>
llvm.used/llvm.compiler.used.  To facilitate linker GC, __attribute__((retain))<br>
causes the section to be placed in a unique section. The separate section<br>
behavior can be undesired in some cases (e.g. poorly written Linux kernel linker<br>
scripts which expect one section per name).<br>
<br>
So in the -fno-function-sections -fno-data-sections case, a retained<br>
function/variable does not cause the whole .text/.data/.rodata to be retained.<br>
<br>
The test llvm/test/CodeGen/X86/elf-retain.ll in <a href="https://reviews.llvm.org/D96837" rel="noreferrer" target="_blank">https://reviews.llvm.org/D96837</a><br>
demonstrates the behavior.  So I am not particularly clear that we should use<br>
llvm.compiler.used/llvm.used to describe __attribute__((retain)) .<br>
<br>
>2. Or add a metadata (like <a href="https://reviews.llvm.org/D96837" rel="noreferrer" target="_blank">https://reviews.llvm.org/D96837</a>)?<br>
><br>
><br>
>I lean to option 1 to leverage the existing mechanism.<br>
>The downside is that clang codegen will have some target inconsistency<br>
>(llvm.compiler.used on ELF while llvm.used on others).<br>
><br>
><br>
><br>
>[1]: The implementation additionally allows GlobalAlias.<br>
>[2]: See <a href="https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order" rel="noreferrer" target="_blank">https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order</a><br>
>"C identifier name sections" for details.<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>