From cdfe790540ee29eb70df4b3f0f7238e9aa9c0713 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 17 Dec 2015 16:22:06 +0000 Subject: [PATCH] Avoid explicit relocation sorting most of the time. 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 | 23 +++++-------------- .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 14 +++++++++++ .../MCTargetDesc/SystemZMCObjectWriter.cpp | 16 ------------- test/MC/ARM/eh-compact-pr0.s | 4 ++-- test/MC/ARM/eh-compact-pr1.s | 2 +- test/MC/ARM/eh-directive-handlerdata.s | 4 ++-- test/MC/ARM/eh-directive-personalityindex.s | 12 +++++----- test/MC/ARM/eh-directive-text-section.s | 2 +- 8 files changed, 32 insertions(+), 45 deletions(-) diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index a92b049d898..e6552beefd0 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -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 &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) { diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index a01c2f8afe0..5b9f02b89be 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -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 &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 MipsRelocs; for (unsigned I = 0, E = Relocs.size(); I != E; ++I) diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp index 2f19127d686..ee1af023769 100644 --- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp +++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp @@ -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 &Relocs) override; }; } // end anonymous namespace @@ -154,20 +152,6 @@ unsigned SystemZObjectWriter::GetRelocType(const MCValue &Target, } } -void SystemZObjectWriter::sortRelocs(const MCAssembler &Asm, - std::vector &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); diff --git a/test/MC/ARM/eh-compact-pr0.s b/test/MC/ARM/eh-compact-pr0.s index 9c0581a722e..66fd4a4efed 100644 --- a/test/MC/ARM/eh-compact-pr0.s +++ b/test/MC/ARM/eh-compact-pr0.s @@ -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: } diff --git a/test/MC/ARM/eh-compact-pr1.s b/test/MC/ARM/eh-compact-pr1.s index 17d32f834e3..9f40593cf43 100644 --- a/test/MC/ARM/eh-compact-pr1.s +++ b/test/MC/ARM/eh-compact-pr1.s @@ -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: ] diff --git a/test/MC/ARM/eh-directive-handlerdata.s b/test/MC/ARM/eh-directive-handlerdata.s index 980a5f05676..c4352e5dee5 100644 --- a/test/MC/ARM/eh-directive-handlerdata.s +++ b/test/MC/ARM/eh-directive-handlerdata.s @@ -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: } diff --git a/test/MC/ARM/eh-directive-personalityindex.s b/test/MC/ARM/eh-directive-personalityindex.s index 6db942503c6..5d537bb04d3 100644 --- a/test/MC/ARM/eh-directive-personalityindex.s +++ b/test/MC/ARM/eh-directive-personalityindex.s @@ -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: } diff --git a/test/MC/ARM/eh-directive-text-section.s b/test/MC/ARM/eh-directive-text-section.s index 32696d5a1da..10ccdd54e50 100644 --- a/test/MC/ARM/eh-directive-text-section.s +++ b/test/MC/ARM/eh-directive-text-section.s @@ -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: ] -- 2.34.1