[cfe-dev] __attribute__((retain)) && llvm.used/llvm.compiler.used
John McCall via cfe-dev
cfe-dev at lists.llvm.org
Wed Feb 24 19:51:43 PST 2021
On 24 Feb 2021, at 13:39, David Blaikie wrote:
> (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)
>
> 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.
I agree that we should go with (1) and give the LLVM construct
consistent semantics to the best of our ability.
John.
>
> On Wed, Feb 24, 2021 at 1:09 AM Fāng-ruì Sòng via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
>> On 2021-02-24, Fāng-ruì Sòng wrote:
>>> Currently __attribute__((used)) lowers to llvm.used.
>>>
>>> * On Mach-O, a GlobalObject in llvm.used gets the
>>> S_ATTR_NO_DEAD_STRIP
>>> attribute, which prevents linker GC (dead stripping).
>>> * On COFF, a non-local-linkage GlobalObject[1] in llvm.used gets the
>>> /INCLUDE: linker option (similar to ELF `ld -u`), which prevents
>>> linker GC.
>>> It should be possible to work with local linkage GlobalObject's as
>>> well but that will require a complex COMDAT dance.
>>> * On ELF, a global object llvm.used can be discarded by
>>> ld.bfd/gold/ld.lld --gc-sections.
>>> (If the section is a C identifier name, __start_/__stop_
>>> relocations
>>> from a live input section can retain the section, even if its
>>> defined
>>> symbols are not referenced. [2] .
>>> I understand that some folks use `__attribute__((used,
>>> section("C_ident")))` and expect the sections to be similar to GC
>>> roots, however,
>>> non-C-identifier cases are very common, too. They don't get
>>> __start_/__stop_ linker magic and the sections can always be GCed.
>>> )
>>>
>>> In LangRef, the description of llvm.used contains:
>>>
>>>> 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.
>>>
>>> Note that the "linker" part does not match the reality on ELF
>>> targets.
>>> It does match the reality on Mach-O and partially on COFF.
>>>
>>> llvm.compiler.used:
>>>
>>>> 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.
>>>
>>> Note that this explicitly mentions linker GC, so this appears to be
>>> the closest thing to __attribute__((used)) on ELF.
>>> However, LangRef also says:
>>>
>>>> This is a rare construct that should only be used in rare
>> circumstances, and should not be exposed to source languages.
>>>
>>>
>>>
>>> My goal is to implement __attribute__((retain)) (which will be in
>>> GCC
>>> 11) on ELF. GCC folks think that 'used' and 'retain are orthogonal.
>>> (see https://reviews.llvm.org/D96838#2578127)
>>>
>>> Shall we
>>>
>>> 1. Lift the source language restriction on llvm.compiler.used and
>>> change __attribute__((used)) to use llvm.compiler.used on ELF.
>>
>> It is too late here and I did not think of it clearly;-)
>>
>> Clarify:
>>
>> 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.
>>
>>
>> __attribute__((retain)) has semantics which are not described by
>> llvm.used/llvm.compiler.used. To facilitate linker GC,
>> __attribute__((retain))
>> causes the section to be placed in a unique section. The separate
>> section
>> behavior can be undesired in some cases (e.g. poorly written Linux
>> kernel
>> linker
>> scripts which expect one section per name).
>>
>> So in the -fno-function-sections -fno-data-sections case, a retained
>> function/variable does not cause the whole .text/.data/.rodata to be
>> retained.
>>
>> The test llvm/test/CodeGen/X86/elf-retain.ll in
>> https://reviews.llvm.org/D96837
>> demonstrates the behavior. So I am not particularly clear that we
>> should
>> use
>> llvm.compiler.used/llvm.used to describe __attribute__((retain)) .
>>
>>> 2. Or add a metadata (like https://reviews.llvm.org/D96837)?
>>>
>>>
>>> I lean to option 1 to leverage the existing mechanism.
>>> The downside is that clang codegen will have some target
>>> inconsistency
>>> (llvm.compiler.used on ELF while llvm.used on others).
>>>
>>>
>>>
>>> [1]: The implementation additionally allows GlobalAlias.
>>> [2]: See
>> https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order
>>> "C identifier name sections" for details.
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
More information about the cfe-dev
mailing list