[PATCH] D19528: [ELF] - Implemented -z combrelocs/nocombreloc.
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Fri May 6 13:35:35 PDT 2016
I was able to manually apply it.
What I did was:
* build clang with shared libraries.
* time with
sudo schedtool -F -p 99 -a 0x4 -e perf stat -r 10 ./bin/clang
* build the patched version of lld
* delete bin/clang-3.9 and lib/*.so
* link again
* time the result
What I got was
* trunk: 0.059005660
* sort on RELATIVE, Symbol, offset, type: 0.040090757
* sort on Symbol, offset, type: 0.042367124
* sort on offset, type: 0.059119353
* sort on RELATIVE, Symbol, offset: 0.040131764
* sort on RELATIVE, Symbol: 0.040396584
* sort on RELATIVE: 0.058322444
* sort on Symbol: 0.039886032
So it looks like the only thing that makes a difference is the symbol.
BTW, one cannot sort .rel.plt, it would be nice to document why.
I think it is better to use stable_sort to be sure we have a
deterministic output without checking fields that don't make a
difference.
So a change sorting only by symbol with stable sort LGTM. Please make
sure you are not computing the number of relative rolocations or
setting any DT_*.
The partial apply that I used for benchmarking was.
Cheers,
Rafael
-------------- next part --------------
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index 9a44339..dffcb9b 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -301,9 +301,9 @@ template <class ELFT> void PltSection<ELFT>::finalize() {
}
template <class ELFT>
-RelocationSection<ELFT>::RelocationSection(StringRef Name)
+RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
: OutputSectionBase<ELFT>(Name, Config->Rela ? SHT_RELA : SHT_REL,
- SHF_ALLOC) {
+ SHF_ALLOC), Sort(Sort) {
this->Header.sh_entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
this->Header.sh_addralign = sizeof(uintX_t);
}
@@ -313,7 +313,21 @@ void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) {
Relocs.push_back(Reloc);
}
+template <class ELFT, class RelTy>
+static bool compRelocations(const RelTy &A, const RelTy &B) {
+ uint8_t AType = A.getType(Config->Mips64EL);
+ uint8_t BType = B.getType(Config->Mips64EL);
+
+ uint32_t I = A.getSymbol(Config->Mips64EL);
+ uint32_t J = B.getSymbol(Config->Mips64EL);
+ if (I != J)
+ return I < J;
+
+ return false;
+}
+
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
+ uint8_t *BufBegin = Buf;
for (const DynamicReloc<ELFT> &Rel : Relocs) {
auto *P = reinterpret_cast<Elf_Rela *>(Buf);
Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
@@ -325,6 +339,15 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
uint32_t SymIdx = (!Rel.UseSymVA && Sym) ? Sym->DynsymIndex : 0;
P->setSymbolAndType(SymIdx, Rel.Type, Config->Mips64EL);
}
+
+ if (!Sort)
+ return;
+ if (Config->Rela)
+ std::stable_sort((Elf_Rela *)BufBegin, (Elf_Rela *)BufBegin + Relocs.size(),
+ compRelocations<ELFT, Elf_Rela>);
+ else
+ std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(),
+ compRelocations<ELFT, Elf_Rel>);
}
template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
diff --git a/ELF/OutputSections.h b/ELF/OutputSections.h
index d8c0e5b..b94f765 100644
--- a/ELF/OutputSections.h
+++ b/ELF/OutputSections.h
@@ -274,7 +274,7 @@ class RelocationSection final : public OutputSectionBase<ELFT> {
typedef typename ELFT::uint uintX_t;
public:
- RelocationSection(StringRef Name);
+ RelocationSection(StringRef Name, bool Sort);
void addReloc(const DynamicReloc<ELFT> &Reloc);
unsigned getRelocOffset();
void finalize() override;
@@ -284,6 +284,7 @@ public:
bool Static = false;
private:
+ bool Sort;
std::vector<DynamicReloc<ELFT>> Relocs;
};
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 8d92229..8fdaebf 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -129,7 +129,8 @@ template <class ELFT> void elf::writeResult(SymbolTable<ELFT> *Symtab) {
GotSection<ELFT> Got;
InterpSection<ELFT> Interp;
PltSection<ELFT> Plt;
- RelocationSection<ELFT> RelaDyn(Config->Rela ? ".rela.dyn" : ".rel.dyn");
+ RelocationSection<ELFT> RelaDyn(Config->Rela ? ".rela.dyn" : ".rel.dyn",
+ true);
StringTableSection<ELFT> DynStrTab(".dynstr", true);
StringTableSection<ELFT> ShStrTab(".shstrtab", false);
SymbolTableSection<ELFT> DynSymTab(*Symtab, DynStrTab);
@@ -165,7 +166,7 @@ template <class ELFT> void elf::writeResult(SymbolTable<ELFT> *Symtab) {
if (Target->UseLazyBinding) {
StringRef S = Config->Rela ? ".rela.plt" : ".rel.plt";
GotPlt.reset(new GotPltSection<ELFT>);
- RelaPlt.reset(new RelocationSection<ELFT>(S));
+ RelaPlt.reset(new RelocationSection<ELFT>(S, false));
}
if (!Config->StripAll) {
StrTab.reset(new StringTableSection<ELFT>(".strtab", false));
More information about the llvm-commits
mailing list