forked from OSchip/llvm-project
Simplify RelrSection<ELFT>::updateAllocSize.
This patch also speeds it up by making some constants compile-time constants. Other than that, NFC. Differential Revision: https://reviews.llvm.org/D49101 llvm-svn: 336614
This commit is contained in:
parent
77eeac3d9e
commit
703c872a4a
lld/ELF
|
@ -1745,53 +1745,47 @@ template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
|
||||||
size_t OldSize = RelrRelocs.size();
|
size_t OldSize = RelrRelocs.size();
|
||||||
RelrRelocs.clear();
|
RelrRelocs.clear();
|
||||||
|
|
||||||
|
// Same as Config->Wordsize but faster because this is a compile-time
|
||||||
|
// constant.
|
||||||
|
const size_t Wordsize = sizeof(typename ELFT::uint);
|
||||||
|
|
||||||
// Number of bits to use for the relocation offsets bitmap.
|
// Number of bits to use for the relocation offsets bitmap.
|
||||||
// These many relative relocations can be encoded in a single entry.
|
// Must be either 63 or 31.
|
||||||
const size_t NBits = 8 * Config->Wordsize - 1;
|
const size_t NBits = Wordsize * 8 - 1;
|
||||||
|
|
||||||
// Get offsets for all relative relocations and sort them.
|
// Get offsets for all relative relocations and sort them.
|
||||||
std::vector<uint64_t> Offsets;
|
std::vector<uint64_t> Offsets;
|
||||||
for (const RelativeReloc &Rel : Relocs) {
|
for (const RelativeReloc &Rel : Relocs)
|
||||||
Offsets.push_back(Rel.getOffset());
|
Offsets.push_back(Rel.getOffset());
|
||||||
}
|
llvm::sort(Offsets.begin(), Offsets.end());
|
||||||
std::sort(Offsets.begin(), Offsets.end());
|
|
||||||
|
|
||||||
uint64_t Base = 0;
|
// For each leading relocation, find following ones that can be folded
|
||||||
typename std::vector<uint64_t>::iterator Curr = Offsets.begin();
|
// as a bitmap and fold them.
|
||||||
while (Curr != Offsets.end()) {
|
for (size_t I = 0, E = Offsets.size(); I < E;) {
|
||||||
uint64_t Current = *Curr;
|
// Add a leading relocation.
|
||||||
assert(Current % 2 == 0);
|
RelrRelocs.push_back(Elf_Relr(Offsets[I]));
|
||||||
|
++I;
|
||||||
|
|
||||||
uint64_t Bits = 0;
|
// Find foldable relocations to create a bitmap.
|
||||||
typename std::vector<uint64_t>::iterator Next = Curr;
|
uint64_t Bitmap = 0;
|
||||||
if (Base > 0 && Base <= Current) {
|
for (size_t J = I; J < E; ++J) {
|
||||||
while (Next != Offsets.end()) {
|
uint64_t Delta = Offsets[J] - Offsets[I];
|
||||||
uint64_t Delta = *Next - Base;
|
|
||||||
// If Next is too far out, it cannot be folded into Curr.
|
// If it is too far, it cannot be folded.
|
||||||
if (Delta >= NBits * Config->Wordsize)
|
if (Delta >= NBits * Wordsize)
|
||||||
break;
|
break;
|
||||||
// If Next is not a multiple of wordsize away, it cannot
|
|
||||||
// be folded into Curr.
|
// If it is not a multiple of wordsize away, it cannot be folded.
|
||||||
if (Delta % Config->Wordsize != 0)
|
if (Delta % Wordsize)
|
||||||
break;
|
break;
|
||||||
// Next can be folded into Curr, add it to the bitmap.
|
|
||||||
Bits |= 1ULL << (Delta / Config->Wordsize);
|
// Fold it.
|
||||||
++Next;
|
Bitmap |= 1ULL << (Delta / Wordsize);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Bits == 0) {
|
if (Bitmap) {
|
||||||
RelrRelocs.push_back(Elf_Relr(Current));
|
RelrRelocs.push_back(Elf_Relr((Bitmap << 1) | 1));
|
||||||
// This is not a continuation entry, only one offset was
|
I += NBits;
|
||||||
// consumed. Set base offset for subsequent bitmap entries.
|
|
||||||
Base = Current + Config->Wordsize;
|
|
||||||
++Curr;
|
|
||||||
} else {
|
|
||||||
RelrRelocs.push_back(Elf_Relr((Bits << 1) | 1));
|
|
||||||
// This is a continuation entry encoding multiple offsets
|
|
||||||
// in a bitmap. Advance base offset by NBits words.
|
|
||||||
Base += NBits * Config->Wordsize;
|
|
||||||
Curr = Next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue