Avoid explicit relocation sorting most of the time.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 17 Dec 2015 16:22:06 +0000 (16:22 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 17 Dec 2015 16:22:06 +0000 (16:22 +0000)
These days relocations are created and stored in a deterministic way.
The order they are created is also suitable for the .o file, so we don't
need an explicit sort.

The last remaining exception is MIPS.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255902 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/ELFObjectWriter.cpp
lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
test/MC/ARM/eh-compact-pr0.s
test/MC/ARM/eh-compact-pr1.s
test/MC/ARM/eh-directive-handlerdata.s
test/MC/ARM/eh-directive-personalityindex.s
test/MC/ARM/eh-directive-text-section.s

index a92b049d8985215db2c158d26a9bc835a17c2d09..e6552beefd01bea53398306e9711ffc4b7698c22 100644 (file)
@@ -1046,28 +1046,17 @@ void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
   WriteWord(EntrySize); // sh_entsize
 }
 
-// ELF doesn't require relocations to be in any order. We sort by the Offset,
-// just to match gnu as for easier comparison. The use type is an arbitrary way
-// of making the sort deterministic.
-static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) {
-  const ELFRelocationEntry &A = *AP;
-  const ELFRelocationEntry &B = *BP;
-  if (A.Offset != B.Offset)
-    return B.Offset - A.Offset;
-  if (B.Type != A.Type)
-    return A.Type - B.Type;
-  llvm_unreachable("ELFRelocs might be unstable!");
-  return 0;
-}
-
 void ELFObjectWriter::writeRelocations(const MCAssembler &Asm,
                                        const MCSectionELF &Sec) {
   std::vector<ELFRelocationEntry> &Relocs = Relocations[&Sec];
 
-  array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel);
+  // We record relocations by pushing to the end of a vector. Reverse the vector
+  // to get the relocations in the order they were created.
+  // In most cases that is not important, but it can be for special sections
+  // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
+  std::reverse(Relocs.begin(), Relocs.end());
 
-  // Sort the relocation entries. Most targets just sort by Offset, but some
-  // (e.g., MIPS) have additional constraints.
+  // Sort the relocation entries. MIPS needs this.
   TargetObjectWriter->sortRelocs(Asm, Relocs);
 
   for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
index a01c2f8afe07332d0946e4d684f8eb71e80c95d5..5b9f02b89be5d374b85ad6b072970418f7db8cd5 100644 (file)
@@ -327,11 +327,25 @@ static void setMatch(MipsRelocationEntry &Hi, MipsRelocationEntry &Lo) {
 //   matching LO;
 // - prefer LOs without a pair;
 // - prefer LOs with higher offset;
+
+static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) {
+  const ELFRelocationEntry &A = *AP;
+  const ELFRelocationEntry &B = *BP;
+  if (A.Offset != B.Offset)
+    return B.Offset - A.Offset;
+  if (B.Type != A.Type)
+    return A.Type - B.Type;
+  return 0;
+}
+
 void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm,
                                      std::vector<ELFRelocationEntry> &Relocs) {
   if (Relocs.size() < 2)
     return;
 
+  // Sorts entries by Offset in descending order.
+  array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel);
+
   // Init MipsRelocs from Relocs.
   std::vector<MipsRelocationEntry> MipsRelocs;
   for (unsigned I = 0, E = Relocs.size(); I != E; ++I)
index 2f19127d6869d272499d191cb9e20684fa5295c2..ee1af023769e8e53274486d44051b2ed4fcbd4f5 100644 (file)
@@ -26,8 +26,6 @@ protected:
   // Override MCELFObjectTargetWriter.
   unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
                         bool IsPCRel) const override;
-  void sortRelocs(const MCAssembler &Asm,
-                  std::vector<ELFRelocationEntry> &Relocs) override;
 };
 } // end anonymous namespace
 
@@ -154,20 +152,6 @@ unsigned SystemZObjectWriter::GetRelocType(const MCValue &Target,
   }
 }
 
-void SystemZObjectWriter::sortRelocs(const MCAssembler &Asm,
-                                     std::vector<ELFRelocationEntry> &Relocs) {
-  // This is OK for SystemZ, except for R_390_TLS_GDCALL/LDCALL relocs.
-  // There is typically another reloc, a R_390_PLT32DBL, on the same
-  // instruction.  This other reloc must come *before* the GDCALL reloc,
-  // or else the TLS linker optimization may generate incorrect code.
-  for (unsigned i = 0, e = Relocs.size(); i + 1 < e; ++i) {
-    if ((Relocs[i + 1].Type == ELF::R_390_TLS_GDCALL ||
-         Relocs[i + 1].Type == ELF::R_390_TLS_LDCALL) &&
-        Relocs[i].Offset == Relocs[i + 1].Offset + 2)
-      std::swap(Relocs[i], Relocs[i + 1]);
-  }
-}
-
 MCObjectWriter *llvm::createSystemZObjectWriter(raw_pwrite_stream &OS,
                                                 uint8_t OSABI) {
   MCELFObjectTargetWriter *MOTW = new SystemZObjectWriter(OSABI);
index 9c0581a722e8718492192db69a6512f83ee24324..66fd4a4efedada0227fece2926592dfa849b8607 100644 (file)
@@ -68,8 +68,8 @@ func2:
 @ RELOC:   Section {
 @ RELOC:     Name: .rel.ARM.exidx.TEST1
 @ RELOC:     Relocations [
-@ RELOC:       0x0 R_ARM_PREL31 .TEST1 0x0
 @ RELOC:       0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0
+@ RELOC:       0x0 R_ARM_PREL31 .TEST1 0x0
 @ RELOC:     ]
 @ RELOC:   }
 
@@ -105,7 +105,7 @@ func2:
 @ RELOC:   Section {
 @ RELOC:     Name: .rel.ARM.exidx.TEST2
 @ RELOC:     Relocations [
-@ RELOC:       0x0 R_ARM_PREL31 .TEST2 0x0
 @ RELOC:       0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0
+@ RELOC:       0x0 R_ARM_PREL31 .TEST2 0x0
 @ RELOC:     ]
 @ RELOC:   }
index 17d32f834e3e1bd1e0afd8289d2615b21866675e..9f40593cf437a983aa00c33379a661dd91283b88 100644 (file)
@@ -68,7 +68,7 @@ func1:
 @ will keep __aeabi_unwind_cpp_pr1.
 @-------------------------------------------------------------------------------
 @ CHECK:     Relocations [
-@ CHECK:       0x0 R_ARM_PREL31 .TEST1 0x0
 @ CHECK:       0x0 R_ARM_NONE __aeabi_unwind_cpp_pr1 0x0
+@ CHECK:       0x0 R_ARM_PREL31 .TEST1 0x0
 @ CHECK:       0x4 R_ARM_PREL31 .ARM.extab.TEST1 0x0
 @ CHECK:     ]
index 980a5f056760e1698e871e29c9e3f5de39a11982..c4352e5dee5889e36d87ea68f0081b04662e6059 100644 (file)
@@ -48,8 +48,8 @@ func1:
 @ RELOC: Section {
 @ RELOC:  Name: .rel.ARM.exidx.TEST1
 @ RELOC:  Relocations [
-@ RELOC:    0x0 R_ARM_PREL31 .TEST1 0x0
 @ RELOC:    0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0
+@ RELOC:    0x0 R_ARM_PREL31 .TEST1 0x0
 @ RELOC:    0x4 R_ARM_PREL31 .ARM.extab.TEST1 0x0
 @ RELOC:  ]
 @ RELOC: }
@@ -108,8 +108,8 @@ func2:
 @ RELOC: Section {
 @ RELOC:  Name: .rel.ARM.exidx.TEST2
 @ RELOC:  Relocations [
-@ RELOC:    0x0 R_ARM_PREL31 .TEST2 0x0
 @ RELOC:    0x0 R_ARM_NONE __aeabi_unwind_cpp_pr1 0x0
+@ RELOC:    0x0 R_ARM_PREL31 .TEST2 0x0
 @ RELOC:    0x4 R_ARM_PREL31 .ARM.extab.TEST2 0x0
 @ RELOC:  ]
 @ RELOC: }
index 6db942503c6d5d8c2674f61fbece5b20458c385a..5d537bb04d3763c9089514ee9e780b7733263740 100644 (file)
@@ -28,8 +28,8 @@ pr0:
 @ RELOC: Section {
 @ RELOC:   Name: .rel.ARM.exidx.pr0
 @ RELOC:   Relocations [
-@ RELOC:     0x0 R_ARM_PREL31 .pr0 0x0
 @ RELOC:     0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0
+@ RELOC:     0x0 R_ARM_PREL31 .pr0 0x0
 @ RELOC:   ]
 @ RELOC: }
 
@@ -57,8 +57,8 @@ pr0_nontrivial:
 @ RELOC: Section {
 @ RELOC:   Name: .rel.ARM.exidx.pr0.nontrivial
 @ RELOC:   Relocations [
-@ RELOC:     0x0 R_ARM_PREL31 .pr0.nontrivial 0x0
 @ RELOC:     0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0
+@ RELOC:     0x0 R_ARM_PREL31 .pr0.nontrivial 0x0
 @ RELOC:   ]
 @ RELOC: }
 
@@ -90,8 +90,8 @@ pr1:
 @ RELOC: Section {
 @ RELOC:   Name: .rel.ARM.exidx.pr1
 @ RELOC:   Relocations [
-@ RELOC:     0x0 R_ARM_PREL31 .pr1 0x0
 @ RELOC:     0x0 R_ARM_NONE __aeabi_unwind_cpp_pr1 0x0
+@ RELOC:     0x0 R_ARM_PREL31 .pr1 0x0
 @ RELOC:     0x4 R_ARM_PREL31 .ARM.extab.pr1 0x0
 @ RELOC:   ]
 @ RELOC: }
@@ -127,8 +127,8 @@ pr1_nontrivial:
 @ RELOC: Section {
 @ RELOC:   Name: .rel.ARM.exidx.pr1.nontrivial
 @ RELOC:   Relocations [
-@ RELOC:     0x0 R_ARM_PREL31 .pr1.nontrivial 0x0
 @ RELOC:     0x0 R_ARM_NONE __aeabi_unwind_cpp_pr1 0x0
+@ RELOC:     0x0 R_ARM_PREL31 .pr1.nontrivial 0x0
 @ RELOC:     0x4 R_ARM_PREL31 .ARM.extab.pr1.nontrivial 0x0
 @ RELOC:   ]
 @ RELOC: }
@@ -161,8 +161,8 @@ pr2:
 @ RELOC: Section {
 @ RELOC:   Name: .rel.ARM.exidx.pr2
 @ RELOC:   Relocations [
-@ RELOC:     0x0 R_ARM_PREL31 .pr2 0x0
 @ RELOC:     0x0 R_ARM_NONE __aeabi_unwind_cpp_pr2 0x0
+@ RELOC:     0x0 R_ARM_PREL31 .pr2 0x0
 @ RELOC:     0x4 R_ARM_PREL31 .ARM.extab.pr2 0x0
 @ RELOC:   ]
 @ RELOC: }
@@ -196,8 +196,8 @@ pr2_nontrivial:
 @ RELOC: Section {
 @ RELOC:   Name: .rel.ARM.exidx.pr2.nontrivial
 @ RELOC:   Relocations [
-@ RELOC:     0x0 R_ARM_PREL31 .pr2.nontrivial 0x0
 @ RELOC:     0x0 R_ARM_NONE __aeabi_unwind_cpp_pr2 0x0
+@ RELOC:     0x0 R_ARM_PREL31 .pr2.nontrivial 0x0
 @ RELOC:     0x4 R_ARM_PREL31 .ARM.extab.pr2.nontrivial 0x0
 @ RELOC:   ]
 @ RELOC: }
index 32696d5a1dad34c879ac0ddca1d529d0ba01a64e..10ccdd54e5019ae4ed0c3ebdde131b545d77b952 100644 (file)
@@ -77,6 +77,6 @@ func1:
 @ add an relocation to __aeabi_unwind_cpp_pr0.
 @-------------------------------------------------------------------------------
 @ CHECK:     Relocations [
-@ CHECK:       0x0 R_ARM_PREL31 .text 0x0
 @ CHECK:       0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0
+@ CHECK:       0x0 R_ARM_PREL31 .text 0x0
 @ CHECK:     ]