[LLVMdev] How to tell whether a GlobalValue is user-defined

David Majnemer david.majnemer at gmail.com
Mon Aug 25 11:36:53 PDT 2014


On Mon, Aug 25, 2014 at 11:08 AM, Akira Hatanaka <ahatanak at gmail.com> wrote:

> I think this is preventing constants in the constant pool (e.g., floating
> point literal) from being placed in the mergeable constant sections?
>
> We want to keep the const arrays declared in the program
> (s_dashArraySize1) out of the mergeable constant sections, but don't mind
>  placing constants in the constant pool or constant arrays that the
> compiler defines, such as switch.table and memset_pattern, in the mergeable
> sections.
>

Ah, ok.

diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 55e1756..93f33af 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -626,15 +626,6 @@ SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind,
           cast<GlobalVariable>(GV)) < 32)
     return UStringSection;

-  if (Kind.isMergeableConst()) {
-    if (Kind.isMergeableConst4())
-      return FourByteConstantSection;
-    if (Kind.isMergeableConst8())
-      return EightByteConstantSection;
-    if (Kind.isMergeableConst16())
-      return SixteenByteConstantSection;
-  }
-
   // Otherwise, if it is readonly, but not something we can specially
optimize,
   // just drop it in .const.
   if (Kind.isReadOnly())

$ echo 'static const int s_dashArraysSize1[4] = {2, 2, 4, 6};

int foo1(int a) {
  return s_dashArraysSize1[a];
}' | ~/llvm/Debug+Asserts/bin/clang -x c -target i686-apple-darwin11 - -S
-o -

        .section        __TEXT,__text,regular,pure_instructions
        .macosx_version_min 10, 7
        .globl  _foo1
        .align  4, 0x90
_foo1:                                  ## @foo1
## BB#0:                                ## %entry
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %eax
        calll   L0$pb
L0$pb:
        popl    %eax
        movl    8(%ebp), %ecx
        movl    %ecx, -4(%ebp)
        movl    -4(%ebp), %ecx
        movl    _s_dashArraysSize1-L0$pb(%eax,%ecx,4), %eax
        addl    $4, %esp
        popl    %ebp
        retl

        .section        __TEXT,__const
        .align  2                       ## @s_dashArraysSize1
_s_dashArraysSize1:
        .long   2                       ## 0x2
        .long   2                       ## 0x2
        .long   4                       ## 0x4
        .long   6                       ## 0x6

Is this what you wanted?


>
>
> On Mon, Aug 25, 2014 at 10:37 AM, David Majnemer <david.majnemer at gmail.com
> > wrote:
>
>> On Mon, Aug 25, 2014 at 9:54 AM, Nick Kledzik <kledzik at apple.com> wrote:
>>
>>>
>>> On Aug 25, 2014, at 8:26 AM, Rafael Espíndola <
>>> rafael.espindola at gmail.com> wrote:
>>>
>>> > On 21 August 2014 19:32, Akira Hatanaka <ahatanak at gmail.com> wrote:
>>> >> Is there a way to distinguish between GlobalValues that are
>>> user-defined and
>>> >> those that are compiler-defined? I am looking for a function that I
>>> can use
>>> >> to tell if a GlobalValue is user-defined , something like
>>> >> "GlobalValue::isUserDefined", which returns true for user-defined
>>> >> GlobalValue.
>>> >>
>>> >> I'm trying to make changes to prevent llvm from placing user-defined
>>> >> constant arrays in the merge able constant sections. Currently, clang
>>> places
>>> >> 16-byte constant arrays that are marked "unnamed_addr" into
>>> __literal16 for
>>> >> macho (see following example).
>>> >>
>>> >> $ cat test1.c
>>> >>
>>> >> static const int s_dashArraysSize1[4] = {2, 2, 4, 6};
>>> >>
>>> >>
>>> >> int foo1(int a) {
>>> >>
>>> >>  return s_dashArraysSize1[a];
>>> >>
>>> >> }
>>> >>
>>> >>
>>> >> $ clang test1.c -S -O3 -o - | tail -n 10
>>> >>
>>> >> .section __TEXT,__literal16,16byte_literals
>>> >>
>>> >> .align 4                       ## @s_dashArraysSize1
>>> >>
>>> >> _s_dashArraysSize1:
>>> >>
>>> >> .long 2                       ## 0x2
>>> >>
>>> >> .long 2                       ## 0x2
>>> >>
>>> >> .long 4                       ## 0x4
>>> >>
>>> >> .long 6                       ## 0x6
>>> >>
>>> >>
>>> >>
>>> >> This is not desirable because macho linker wasn't originally designed
>>> to
>>> >> handle user-defined symbols in those sections and having to handle
>>> them
>>> >> complicates the linker. Also, there is no benefit in doing so, since
>>> the
>>> >> linker currently doesn't try to merge user-defined variables anyway.
>>> >
>>> > What does "user-defined" means in here? Since the linker can is
>>> > involved, I assume it has something to do with the final symbol name.
>>> >
>>> > At the linker level (symbol names, sections, atoms, relocations, etc),
>>> > what exactly that is not supported?
>>>
>>>
>>> The literalN sections were developed long ago to support coalescing of
>>> unnamed constants like 9.897 in source code for architectures that could
>>> not embed large constants in instructions.  The linker could knew how to
>>> break up the section (e.g. __literal8 is always 8 byte chunks) and coalesce
>>> copies by content.
>>>
>>> ~6 years ago we discovered that gcc would sometimes put user named
>>> constants into the literal sections (e.g. const double foo 9.897).  This
>>> was an issue because C language rules say &a != &b, but if ‘a’ and ‘b’ are
>>> the contain the same literal value from different translation units, the
>>> linker could merge them to the same address.  For whatever reason, we could
>>> not fix gcc, so we changed to linker to never coalesce items in literal
>>> sections if there was a (non ‘L’ and non ‘l’) symbol on it.
>>>
>>> The current state of LLVM is that is it going out of its way to move
>>> “named” constants from __const section to __literalN section. But the only
>>> possible advantage to doing that is that the hopes that the linker might
>>> coalesce it.  But the linker won’t coalesce it because it is named.  So, is
>>> there a way to keep the named values in the __const section?
>>>
>>
>> I believe the following patch would be the minimal needed to do this,
>> there is some dead code that could be removed as well.
>>
>> diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
>> b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
>> index 55e1756..bf78ce1 100644
>> --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
>> +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
>> @@ -667,12 +667,6 @@
>> TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind,
>>    if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
>>      return ConstDataSection;
>>
>> -  if (Kind.isMergeableConst4())
>> -    return FourByteConstantSection;
>> -  if (Kind.isMergeableConst8())
>> -    return EightByteConstantSection;
>> -  if (Kind.isMergeableConst16())
>> -    return SixteenByteConstantSection;
>>    return ReadOnlySection;  // .const
>>  }
>>
>>
>>>
>>> -Nick
>>>
>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>>
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140825/7bcb48af/attachment.html>


More information about the llvm-dev mailing list