[PATCH] [RFC][PATCH] Minor opt to access pointers to globals via pcrel GOT entries

Rafael EspĂ­ndola rafael.espindola at gmail.com
Thu Feb 5 12:55:42 PST 2015

> The problem of not doing an early pass is because we can't rely on the global declaration order - if we hit the 'got equivalent user' before keeping track of the 'global equivalent', we have to find the global variable for 'global equivalent' after its MCSymbol, because at that point we already lost the GlobalVariable reference. One could argue that we can find this GlobalVariable again by scanning the original cstexpr where we got the MCExpr from, but this also would require complex logic to handle all different types of cstexpr that could lead to a relocatable expression. Gonna add a comment about that.

I see. Given just the symbol it is not trivial to find about
unnamed_addr for example.

> ================
> Comment at: lib/CodeGen/AsmPrinter/AsmPrinter.cpp:2081
> @@ +2080,3 @@
> +  int64_t BaseSymOff = -Offset;
> +  if (BaseSym != &MV.getSymB()->getSymbol() || MV.getConstant() != BaseSymOff)
> +    return;
> ----------------
> rafael wrote:
>> I am not sure I understand why the  MV.getConstant() != BaseSymOff restriction is necessary.
>> If we have
>> -------------------------
>> .globl  _proxy
>> _proxy:
>>  .quad   _foo
>>  .globl  _delta
>> _delta:
>>  .long   _proxy-_delta + 42
>> ------------------------------------
>> It can be converted to
>> -----------------------------
>> .globl  _delta
>> _delta:
>>  .long   _foo at GOTPCREL + 42
>> ----------------------------
>> no? It works on ELF at least.
> Note that the reason why BaseSymOff exists is to ensure that "." is properly matched, i.e., we need to know that the symbol we are subtracting from is indeed the "PC" location. Take your example:
>   delta:
>     .long (.Lproxy-delta)+42
>     .size delta, 4
> Here, "." == "delta" and BaseSymOff == 0, since we're emitting the first and only element of delta. Now, if we're emitting the GOTPCREL into, let's say, the second element of an array where each element has 4 bytes, we need "." == "delta+4" and BaseSymOff == 4, since we want to be sure we're dealing with a pc relative location:
>   delta:
>     .long 33
>     .long (.Lproxy-(delta+4))+42 ==> .long (.Lproxy-delta)+38
>     .size delta, 8
> That said, the restriction isn't necessary as long as we have BaseSymOff contained into the final offset value. I didn't think of that use before although it's valid and looks like it could be (?) used by front-end writers to do all sort of black magic.
> It's a small change, gonna include that in the patch and write a test for it using a cstexpr that also adds one more constant.

Awesome. It is a case where doing the more general solution is
probably simpler (or at least easier to understand).


More information about the llvm-commits mailing list