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:
Rui Ueyama 2018-07-09 22:29:57 +00:00
parent 77eeac3d9e
commit 703c872a4a
1 changed files with 32 additions and 38 deletions

View File

@ -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;
} }
} }