[PATCH] D19995: Optimize access to global variable references in PIE mode when linker supports copy relocations for PIE

John McCall via llvm-commits llvm-commits at lists.llvm.org
Sun May 8 22:13:35 PDT 2016


rjmccall added a comment.

In http://reviews.llvm.org/D19995#424356, @joerg wrote:

> In http://reviews.llvm.org/D19995#424345, @rjmccall wrote:
>
> > It seems reasonable to me to have an option enabling the use of copy relocations for globals,
> >  and I agree with David that that option should logically be applicable to PIE.  I would also tend
> >  to agree with Joerg that that option should default to off, even in non-PIC modes, but it's not my call.
>
>
> Non-PIC use of copy relocations is practically unavoidable


This is not even slightly true.  There is absolutely nothing preventing you from using a GOT-style relocation in non-PIC mode.  Even if you didn't have linker support for a non-relative relocation to a GOT entry (on platforms where it matters), you can easily fake one up with weak symbols.

I mean, it doesn't really affect me, so feel free to over-use copy relocations, but you don't actually have to.

> > RE: the performance impact of relying on the linker to optimize accesses: it certainly can increase

> 

> >  register pressure, but it shouldn't in the most common cases where the access sequence ends in

> 

> >  putting a new value in a GPR anyway (usually either the address of the variable or something loaded

> 

> >  from it).

> 

> 

> Evidence for that? In PIC/PIE mode, obtaining the address of a variable is always either a load

>  (generic case via GOT) or at least an address computation (%rip + offset). Even for the second case,

>  I don't think full folding without scratch register is a very common case.


The access sequence doesn't end with constructing the address.  If you're loading from the address or moving it into a register for some more complicated action, you're clobbering a register anyway and can just use that as your scratch register.  That's only not true when (1) you're loading into a non-GPR, e.g. an xmm register, or (2) you're just storing to the variable.  As a general rule, those cases are a lot less common, especially with an external variable.

> > More importantly, I don't really understand how you can avoid this without compiling code assuming

> 

> >  that all globals can be copy-relocated, since the *compiler* doesn't know whether an external symbol

> 

> >  is defined as protected or default.  (Unless that's exactly what we're doing — are people really this

> 

> >  fast-and-loose in ELF land?)

> 

> 

> The (sane) default behavior for PIC and PIE code is to access external symbols with default visibility

>  via the GOT.


I completely agree.  I don't see why this should even be specific to PIC, but like I've said before, that's not really my call to make.

> > RE: the semantic problems with copy relocations exposing the layout of globals: yes, binary compatibility

> 

> >  problems usually don't exist when you recompile all the dependent code.  I can understand why system

> 

> >  maintainers wouldn't be thrilled with the idea that certain kinds of updates to system libraries can't be

> 

> >  made without recompiling the entire user space, though.

> 

> 

> Yes, this is exactly one of the core reasons why I am adamant against supporting copy relocations for PIE.

>  It forces real performance degradations for library interfaces, that often have a far more measurable impact.


Right.

My general take on copy relocations is that they're a very useful feature that should have been reserved for specific use cases as opposed to being generally exploited to optimize executables over libraries.  (Interesting use case for copy relocations: libraries that export version-specific constant values that are frequently accessed by clients. For example, you could imagine libc exporting the system page size.)


http://reviews.llvm.org/D19995





More information about the llvm-commits mailing list