[lld] r276146 - Create thunks before regular relocation scan.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 20 10:58:08 PDT 2016
Author: rafael
Date: Wed Jul 20 12:58:07 2016
New Revision: 276146
URL: http://llvm.org/viewvc/llvm-project?rev=276146&view=rev
Log:
Create thunks before regular relocation scan.
We will need to do something like this to support range extension
thunks since that process is iterative.
Doing this also has the advantage that when doing the regular
relocation scan the offset in the output section is known and we can
just store that. This reduces the number of times we have to run
getOffset and I think will allow a more specialized .eh_frame
representation.
By itself this is already a performance win.
firefox
master 7.295045737
patch 7.209466989 0.98826892235
chromium
master 4.531254468
patch 4.509221804 0.995137623774
chromium fast
master 1.836928973
patch 1.823805241 0.992855612714
the gold plugin
master 0.379768791
patch 0.380043405 1.00072310839
clang
master 0.642698284
patch 0.642215663 0.999249070657
llvm-as
master 0.036665467
patch 0.036456225 0.994293213284
the gold plugin fsds
master 0.40395817
patch 0.404384555 1.0010555177
clang fsds
master 0.722045545
patch 0.720946135 0.998477367518
llvm-as fsds
master 0.03292646
patch 0.032759965 0.994943428477
scylla
master 3.427376378
patch 3.368316181 0.98276810292
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/Relocations.h
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=276146&r1=276145&r2=276146&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Jul 20 12:58:07 2016
@@ -338,7 +338,7 @@ void InputSectionBase<ELFT>::relocate(ui
const unsigned Bits = sizeof(uintX_t) * 8;
for (const Relocation<ELFT> &Rel : Relocations) {
- uintX_t Offset = Rel.InputSec->getOffset(Rel.Offset);
+ uintX_t Offset = Rel.Offset;
uint8_t *BufLoc = Buf + Offset;
uint32_t Type = Rel.Type;
uintX_t A = Rel.Addend;
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=276146&r1=276145&r2=276146&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Jul 20 12:58:07 2016
@@ -1278,7 +1278,7 @@ template <class ELFT>
typename ELFT::uint DynamicReloc<ELFT>::getOffset() const {
if (OutputSec)
return OutputSec->getVA() + OffsetInSec;
- return InputSec->OutSec->getVA() + InputSec->getOffset(OffsetInSec);
+ return InputSec->OutSec->getVA() + OffsetInSec;
}
template <class ELFT>
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=276146&r1=276145&r2=276146&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed Jul 20 12:58:07 2016
@@ -548,9 +548,19 @@ static void scanRelocs(InputSectionBase<
while (PieceI != PieceE &&
(PieceI->InputOff + PieceI->size() <= RI.r_offset))
++PieceI;
- if (PieceI != PieceE && PieceI->InputOff <= RI.r_offset &&
- PieceI->OutputOff == (uintX_t)-1)
- continue;
+
+ // Compute the offset of this section in the output section. We do it here
+ // to try to compute it only once.
+ uintX_t Offset;
+ if (PieceI != PieceE) {
+ assert(PieceI->InputOff <= RI.r_offset && "Relocation not in any piece");
+ if (PieceI->OutputOff == (uintX_t)-1)
+ continue;
+ Offset = PieceI->OutputOff + RI.r_offset - PieceI->InputOff;
+ assert(Offset == C.getOffset(RI.r_offset));
+ } else {
+ Offset = C.getOffset(RI.r_offset);
+ }
// This relocation does not require got entry, but it is relative to got and
// needs it to be created. Here we request for that.
@@ -559,8 +569,8 @@ static void scanRelocs(InputSectionBase<
uintX_t Addend = computeAddend(File, Buf, E, RI, Expr, Body);
- if (unsigned Processed = handleTlsRelocation<ELFT>(
- Type, Body, C, RI.r_offset, Addend, Expr)) {
+ if (unsigned Processed =
+ handleTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr)) {
I += (Processed - 1);
continue;
}
@@ -581,17 +591,17 @@ static void scanRelocs(InputSectionBase<
// relocation. We can process some of it and and just ask the dynamic
// linker to add the load address.
if (!Constant)
- AddDyn({Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend});
+ AddDyn({Target->RelativeRel, &C, Offset, true, &Body, Addend});
// If the produced value is a constant, we just remember to write it
// when outputting this section. We also have to do it if the format
// uses Elf_Rel, since in that case the written value is the addend.
if (Constant || !RelTy::IsRela)
- C.Relocations.push_back({Expr, Type, &C, RI.r_offset, Addend, &Body});
+ C.Relocations.push_back({Expr, Type, &C, Offset, Addend, &Body});
} else {
// We don't know anything about the finaly symbol. Just ask the dynamic
// linker to handle the relocation for us.
- AddDyn({Target->getDynRel(Type), &C, RI.r_offset, false, &Body, Addend});
+ AddDyn({Target->getDynRel(Type), &C, Offset, false, &Body, Addend});
// MIPS ABI turns using of GOT and dynamic relocations inside out.
// While regular ABI uses dynamic relocations to fill up GOT entries
// MIPS ABI requires dynamic linker to fills up GOT entries using
@@ -612,14 +622,6 @@ static void scanRelocs(InputSectionBase<
continue;
}
- // Some targets might require creation of thunks for relocations.
- // Now we support only MIPS which requires LA25 thunk to call PIC
- // code from non-PIC one, and ARM which requires interworking.
- if (Expr == R_THUNK_ABS || Expr == R_THUNK_PC || Expr == R_THUNK_PLT_PC) {
- auto *Sec = cast<InputSection<ELFT>>(&C);
- addThunk<ELFT>(Type, Body, *Sec);
- }
-
// At this point we are done with the relocated position. Some relocations
// also require us to create a got or plt entry.
@@ -676,19 +678,6 @@ static void scanRelocs(InputSectionBase<
}
}
-template <class ELFT> void scanRelocations(InputSection<ELFT> &C) {
- typedef typename ELFT::Shdr Elf_Shdr;
-
- // Scan all relocations. Each relocation goes through a series
- // of tests to determine if it needs special treatment, such as
- // creating GOT, PLT, copy relocations, etc.
- // Note that relocations for non-alloc sections are directly
- // processed by InputSection::relocateNonAlloc.
- if (C.getSectionHdr()->sh_flags & SHF_ALLOC)
- for (const Elf_Shdr *RelSec : C.RelocSections)
- scanRelocations(C, *RelSec);
-}
-
template <class ELFT>
void scanRelocations(InputSectionBase<ELFT> &S,
const typename ELFT::Shdr &RelSec) {
@@ -699,10 +688,35 @@ void scanRelocations(InputSectionBase<EL
scanRelocs(S, EObj.rels(&RelSec));
}
-template void scanRelocations<ELF32LE>(InputSection<ELF32LE> &);
-template void scanRelocations<ELF32BE>(InputSection<ELF32BE> &);
-template void scanRelocations<ELF64LE>(InputSection<ELF64LE> &);
-template void scanRelocations<ELF64BE>(InputSection<ELF64BE> &);
+template <class ELFT, class RelTy>
+static void createThunks(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
+ const elf::ObjectFile<ELFT> &File = *C.getFile();
+ for (const RelTy &Rel : Rels) {
+ SymbolBody &Body = File.getRelocTargetSym(Rel);
+ uint32_t Type = Rel.getType(Config->Mips64EL);
+ RelExpr Expr = Target->getRelExpr(Type, Body);
+ if (!isPreemptible(Body, Type) && needsPlt(Expr))
+ Expr = fromPlt(Expr);
+ Expr = Target->getThunkExpr(Expr, Type, File, Body);
+ // Some targets might require creation of thunks for relocations.
+ // Now we support only MIPS which requires LA25 thunk to call PIC
+ // code from non-PIC one, and ARM which requires interworking.
+ if (Expr == R_THUNK_ABS || Expr == R_THUNK_PC || Expr == R_THUNK_PLT_PC) {
+ auto *Sec = cast<InputSection<ELFT>>(&C);
+ addThunk<ELFT>(Type, Body, *Sec);
+ }
+ }
+}
+
+template <class ELFT>
+void createThunks(InputSectionBase<ELFT> &S,
+ const typename ELFT::Shdr &RelSec) {
+ ELFFile<ELFT> &EObj = S.getFile()->getObj();
+ if (RelSec.sh_type == SHT_RELA)
+ createThunks(S, EObj.relas(&RelSec));
+ else
+ createThunks(S, EObj.rels(&RelSec));
+}
template void scanRelocations<ELF32LE>(InputSectionBase<ELF32LE> &,
const ELF32LE::Shdr &);
@@ -712,5 +726,14 @@ template void scanRelocations<ELF64LE>(I
const ELF64LE::Shdr &);
template void scanRelocations<ELF64BE>(InputSectionBase<ELF64BE> &,
const ELF64BE::Shdr &);
+
+template void createThunks<ELF32LE>(InputSectionBase<ELF32LE> &,
+ const ELF32LE::Shdr &);
+template void createThunks<ELF32BE>(InputSectionBase<ELF32BE> &,
+ const ELF32BE::Shdr &);
+template void createThunks<ELF64LE>(InputSectionBase<ELF64LE> &,
+ const ELF64LE::Shdr &);
+template void createThunks<ELF64BE>(InputSectionBase<ELF64BE> &,
+ const ELF64BE::Shdr &);
}
}
Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=276146&r1=276145&r2=276146&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Wed Jul 20 12:58:07 2016
@@ -73,12 +73,13 @@ template <class ELFT> struct Relocation
SymbolBody *Sym;
};
-template <class ELFT> void scanRelocations(InputSection<ELFT> &);
-
template <class ELFT>
void scanRelocations(InputSectionBase<ELFT> &, const typename ELFT::Shdr &);
template <class ELFT>
+void createThunks(InputSectionBase<ELFT> &, const typename ELFT::Shdr &);
+
+template <class ELFT>
static inline typename ELFT::uint getAddend(const typename ELFT::Rel &Rel) {
return 0;
}
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=276146&r1=276145&r2=276146&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Wed Jul 20 12:58:07 2016
@@ -1496,6 +1496,7 @@ ARMTargetInfo::ARMTargetInfo() {
PltHeaderSize = 20;
// ARM uses Variant 1 TLS
TcbSize = 8;
+ NeedsThunks = true;
}
RelExpr ARMTargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
@@ -1836,6 +1837,7 @@ template <class ELFT> MipsTargetInfo<ELF
PltHeaderSize = 32;
CopyRel = R_MIPS_COPY;
PltRel = R_MIPS_JUMP_SLOT;
+ NeedsThunks = true;
if (ELFT::Is64Bits) {
RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
TlsGotRel = R_MIPS_TLS_TPREL64;
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=276146&r1=276145&r2=276146&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Wed Jul 20 12:58:07 2016
@@ -92,6 +92,8 @@ public:
// Set to 0 for variant 2
unsigned TcbSize = 0;
+ bool NeedsThunks = false;
+
virtual RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
RelExpr Expr) const;
virtual void relaxGot(uint8_t *Loc, uint64_t Val) const;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=276146&r1=276145&r2=276146&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Jul 20 12:58:07 2016
@@ -49,6 +49,9 @@ private:
void copyLocalSymbols();
void addReservedSymbols();
std::vector<OutputSectionBase<ELFT> *> createSections();
+ void forEachRelSec(
+ std::function<void(InputSectionBase<ELFT> &, const typename ELFT::Shdr &)>
+ Fn);
void finalizeSections();
void addPredefinedSections();
bool needsGot();
@@ -633,6 +636,34 @@ template <class ELFT> static void sortCt
}
template <class ELFT>
+void Writer<ELFT>::forEachRelSec(
+ std::function<void(InputSectionBase<ELFT> &, const typename ELFT::Shdr &)>
+ Fn) {
+ for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :
+ Symtab.getObjectFiles()) {
+ for (InputSectionBase<ELFT> *C : F->getSections()) {
+ if (isDiscarded(C))
+ continue;
+ // Scan all relocations. Each relocation goes through a series
+ // of tests to determine if it needs special treatment, such as
+ // creating GOT, PLT, copy relocations, etc.
+ // Note that relocations for non-alloc sections are directly
+ // processed by InputSection::relocateNonAlloc.
+ if (!(C->getSectionHdr()->sh_flags & SHF_ALLOC))
+ continue;
+ if (auto *S = dyn_cast<InputSection<ELFT>>(C)) {
+ for (const Elf_Shdr *RelSec : S->RelocSections)
+ Fn(*S, *RelSec);
+ continue;
+ }
+ if (auto *S = dyn_cast<EhInputSection<ELFT>>(C))
+ if (S->RelocSection)
+ Fn(*S, *S->RelocSection);
+ }
+ }
+}
+
+template <class ELFT>
std::vector<OutputSectionBase<ELFT> *> Writer<ELFT>::createSections() {
std::vector<OutputSectionBase<ELFT> *> Result;
@@ -705,26 +736,16 @@ template <class ELFT> void Writer<ELFT>:
Out<ELFT>::EhFrame->finalize();
}
- // Scan relocations. This must be done after every symbol is declared so that
- // we can correctly decide if a dynamic relocation is needed.
- for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :
- Symtab.getObjectFiles()) {
- for (InputSectionBase<ELFT> *C : F->getSections()) {
- if (isDiscarded(C))
- continue;
- if (auto *S = dyn_cast<InputSection<ELFT>>(C)) {
- scanRelocations(*S);
- continue;
- }
- if (auto *S = dyn_cast<EhInputSection<ELFT>>(C))
- if (S->RelocSection)
- scanRelocations(*S, *S->RelocSection);
- }
- }
+ if (Target->NeedsThunks)
+ forEachRelSec(createThunks<ELFT>);
for (OutputSectionBase<ELFT> *Sec : OutputSections)
Sec->assignOffsets();
+ // Scan relocations. This must be done after every symbol is declared so that
+ // we can correctly decide if a dynamic relocation is needed.
+ forEachRelSec(scanRelocations<ELFT>);
+
// Now that we have defined all possible symbols including linker-
// synthesized ones. Visit all symbols to give the finishing touches.
std::vector<DefinedCommon *> CommonSymbols;
More information about the llvm-commits
mailing list