[PATCH] Re-enable a hook in MCELFObjectTargetWriter to allow target-specific relocationtable sorting and use this hook for Mips.
Vladimir Stefanovic
vladimir.stefanovic at imgtec.com
Fri Mar 13 17:25:13 PDT 2015
REPOSITORY
rL LLVM
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:29
@@ +28,3 @@
+struct MipsRelocationEntry {
+ MipsRelocationEntry(ELFRelocationEntry &R, unsigned MatchingLo):
+ Reloc(R), SortOffset(R.Offset), MatchingLoType(MatchingLo),
----------------
rafael wrote:
> Please use the same names for arguments and fields so that you have
> ... : foo(foo), bar(bar) ... {
OK.
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:33
@@ +32,3 @@
+
+ ELFRelocationEntry Reloc;
+ // SortOffset equals Reloc.Offset except for the *HI16 relocations, for which
----------------
rafael wrote:
> Can this be a
>
> const ELFRelocationEntry &Reloc;
>
> ?
It can be const, but '&' would bring down the last step, which copies sorted MipsRelocs back to Relocs.
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:39
@@ +38,3 @@
+ // For *HI16 relocations, a matching relocation type for Reloc.Type.
+ int64_t MatchingLoType;
+ // True when this is a *LO16 relocation preceded with a matching *HI16
----------------
rafael wrote:
> Why do you need to store this?
It isn't necessary, I can always call getMatchingLoType() instead, which I did in the updated patch.
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:278
@@ +277,3 @@
+
+ // Don't check if symbol is local for non-*GOT16 relocations.
+ if (!(Reloc.Type == ELF::R_MIPS_GOT16
----------------
rafael wrote:
> Why is that?
Just to skip calling Asm.getSymbolData() for the relocations that will return R_MIPS_NONE anyway. I removed it.
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:285
@@ +284,3 @@
+ const MCSymbolData &SD = Asm.getSymbolData(*Reloc.Symbol);
+ if (MCELF::GetBinding(SD) == ELF::STB_LOCAL) {
+ if (Reloc.Type == ELF::R_MIPS_GOT16) return ELF::R_MIPS_LO16;
----------------
rafael wrote:
> Use an earlier return
>
> if (MCELF::GetBinding(SD) != ELF::STB_LOCAL)
> return ELF::R_MIPS_NONE;
>
OK.
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:309
@@ +308,3 @@
+ Hi.IsNextMatchingLo = true;
+ Hi.SortOffset = Lo.Reloc.Offset -1;
+}
----------------
rafael wrote:
> Why -1?
> This looks like a leftover from the sort function not considering a relocation own offset to break ties.
'-1' simplifies the sort function.
If omitting '-1', the rules for entries with the same SortOffset would be:
-if one is %hi, that one should be first;
-if both are %hi, sort them by Offset (in descending order).
So '-1' practically applies the first rule, and the sorting function only needs to handle the second case.
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:335
@@ +334,3 @@
+// rule, we try to replicate binutils' behaviour, for no other reason than
+// consistency with what gnu as produces.
+//
----------------
rafael wrote:
> This wording is a bit soft.
>
> Assembly is user input, and if gnu as matches a %lo and a %hi differently from what we do we would be producing a .o with different semantics.
How about:
// When there is more than one way to sort the table while respecting the ABI
// rule, we try to implement the same semantics as gnu as, ie. we try to match
// a HI and a LO the same way gnu as does.
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:344
@@ +343,3 @@
+// When there are more HIs matched with one LO, sort them in descending order by
+// offset.
+//
----------------
rafael wrote:
> This description makes it sound like that given
>
> lui $2, %hi(func2)
> lui $2, %hi(func2)
> addiu $2, $2, %lo(func2)
> addiu $2, $2, %lo(func2)
>
> the second %hi would be matched with the second %lo, but in a previous comment you said that gas produces
>
>
> 00000004 00000605 R_MIPS_HI16 00000000 func2
> 00000008 00000606 R_MIPS_LO16 00000000 func2
> 00000000 00000605 R_MIPS_HI16 00000000 func2
> 0000000c 00000606 R_MIPS_LO16 00000000 func2
>
> That is, the second %hi (offset 4) is matched with the first lo (offset 8).
>
That's right, because the second %hi is already followed by a %lo. So the sentence about finding the matching %lo applies only to the first %hi, which gets matched with the second %lo.
I tried to be clearer in the next paragraph, with "don't look for a 'better' match for the HIs that are already followed with a matching LO".
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:353
@@ +352,3 @@
+ std::vector<ELFRelocationEntry> &Relocs) {
+ if (Relocs.size() < 2) return;
+
----------------
rafael wrote:
> Please git-clang-format the patch.
Sure.
================
Comment at: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp:366
@@ +365,3 @@
+ // Also find HIs and LOs that are already matched.
+ if (I > 0 && areMatchingHiAndLo(MipsRelocs[I], MipsRelocs[I-1]))
+ setMatch(MipsRelocs[I], MipsRelocs[I-1]);
----------------
rafael wrote:
> Why is this first check for I and I-1 necessary? The main loop should handle it, no?
It finds 'non-free' %lo's, ie. the ones that are already preceded with a %hi. Then it's easier for the main loop to find a 'free' %lo for a %hi, which are preferred over the 'non-free' ones. As an addition, it remembers %hi's with a matched %lo so the main loop can early exit for them.
================
Comment at: test/MC/Mips/sort-relocation-table.s:6
@@ +5,3 @@
+# corresponding *LO16 relocation against the same symbol.
+
+# TODO: Add mips16 and micromips tests.
----------------
rafael wrote:
> Can you add a comment about the gnu as target and command line that can be used to compare the result of this file?
Added.
http://reviews.llvm.org/D7414
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
More information about the llvm-commits
mailing list