This is an archive of the discontinued LLVM Phabricator instance.

Don't access items in .sdata section using gp-relative addressing when target is NaCl.
AbandonedPublic

Authored by sstankovic on Jun 9 2014, 8:45 AM.

Details

Reviewers
mseaborn
Summary

[mips] Don't access items in .sdata section using gp-relative addressing when target is NaCl.

Diff Detail

Event Timeline

sstankovic updated this revision to Diff 10238.Jun 9 2014, 8:45 AM
sstankovic retitled this revision from to Don't access items in .sdata section using gp-relative addressing when target is NaCl..
sstankovic updated this object.
sstankovic edited the test plan for this revision. (Show Details)
sstankovic added a reviewer: mseaborn.
sstankovic added subscribers: Unknown Object (MLST), petarj.
mseaborn edited edge metadata.Jun 9 2014, 9:55 AM

Can you provide some more context in the commit message, please? Why don't you want to use gp-relative addressing when targeting NaCl? Is this necessary or just desirable?

Here is some explanation for it, but I'm not sure whether this should be in the commit message. This is also not supported in Linux, but I don't know the reason for it. But even if we enable gp-relative addressing in NaCl, it wouldn't work because MIPS Gold linker currently doesn't support it. For gp-relative addressing to work, linker needs to emit together all the sections that are accessed using gp-relative addressing (.got section first, followed by various small-data sections (.sdata, .sbss, ...)). This is currently not implemented in MIPS Gold. (In GNU ld, this section ordering is specified in ld's internal linker script, but Gold doesn't have internal linker script.)

sstankovic updated this revision to Diff 10273.Jun 10 2014, 6:14 AM
sstankovic edited edge metadata.

Presumably the reason that UseSmallSection is disabled for Linux is that LLVM is assuming that it might be being used with Gold?

It isn't related to Gold because apart from PNaCl, MIPS Gold is not used anywhere else; MIPS Gold isn't even committed to the FSF binutils - the patch is still in review on binutils mailing list.

I suppose that the reason why it's disabled in Linux is because gp-relative addressing can only address 64K area (MIPS has 16-bit load/store offsets). That's probably why it's never used for PIC code (both Linux and non-Linux), because in PIC code .got section is also accessed using gp-relative addressing, so that leaves even less space for data items to be accessed using gp-relative addressing.

If you don't explain this in the commit message or in the code, how would someone reading the
source code know the reason for making UseSmallSection conditional on !isTargetNaCl()? How
would someone maintaining the code know whether the !isTargetNaCl() check could be removed?

I think you should add a comment explaining this in the code.

When I said that I was not sure whether this should be in the commit message I was referring to Gold (I think we should not mention Gold in LLVM code or commit message).

I updated the patch with the comment that in NaCl we disable gp-relative addressing because it can address 64K area only.

Would it make sense to turn off use of sdata by default, and have it only enabled by a compiler flag or llc flag? That would be cleaner and is not very difficult to do. It should come with a warning like "this is an optimisation that might cause moderate-sized programs to fail to link".

This is what Mips gcc for Linux does - gp-relative addressing is not enabled by default, but it can be requested at command line (gcc doesn't issue a warning though). I also tested a bare-metal Mips gcc toolchain, and it has different behavior - gp-relative addressing is enabled by default. I'll ask Daniel Sanders (LLVM code owner for MIPS backend) whether we should add a command line flag for this.

BTW, have you looked at the GlobalMerge pass (lib/Transforms/Scalar/GlobalMerge.cpp)? That is used on ARM and gives a similar kind of optimisation to the MIPS sdata section. It will reuse the computation of a base address within the data segment for multiple variables, rather than computing a data segment address for each variable that's referenced. GlobalMerge is a more robust way of doing this optimisation than sdata, though it only works when the referenced variables are within the same compilation unit being compiled by llc.

I enabled this pass for Mips and experimented with it by running some tests. When the pass changes the code, it usually does create smaller code. But there are also cases when the pass actually produces larger code. I'll do more investigation on this.

sstankovic abandoned this revision.Nov 4 2014, 3:34 PM

Implemented in D4903.