[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