[ELF] splitStrings: replace entSize==1 special case with manual loop unswitch. NFC

My x86-64 lld executable is actually smaller.
This commit is contained in:
Fangrui Song 2022-01-30 17:15:45 -08:00
parent 175145e3f4
commit 457273fda5
2 changed files with 20 additions and 20 deletions

View File

@ -1358,16 +1358,12 @@ void EhInputSection::split(ArrayRef<RelTy> rels) {
}
static size_t findNull(StringRef s, size_t entSize) {
// Optimize the common case.
if (entSize == 1)
return s.find(0);
for (unsigned i = 0, n = s.size(); i != n; i += entSize) {
const char *b = s.begin() + i;
if (std::all_of(b, b + entSize, [](char c) { return c == 0; }))
return i;
}
return StringRef::npos;
llvm_unreachable("");
}
SyntheticSection *MergeInputSection::getParent() const {
@ -1376,20 +1372,24 @@ SyntheticSection *MergeInputSection::getParent() const {
// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
void MergeInputSection::splitStrings(ArrayRef<uint8_t> data, size_t entSize) {
size_t off = 0;
void MergeInputSection::splitStrings(StringRef s, size_t entSize) {
const bool live = !(flags & SHF_ALLOC) || !config->gcSections;
StringRef s = toStringRef(data);
while (!s.empty()) {
size_t end = findNull(s, entSize);
if (end == StringRef::npos)
fatal(toString(this) + ": string is not null terminated");
size_t size = end + entSize;
pieces.emplace_back(off, xxHash64(s.substr(0, size)), live);
s = s.substr(size);
off += size;
const char *p = s.data(), *end = s.data() + s.size();
if (!std::all_of(end - entSize, end, [](char c) { return c == 0; }))
fatal(toString(this) + ": string is not null terminated");
if (entSize == 1) {
// Optimize the common case.
do {
size_t size = strlen(p) + 1;
pieces.emplace_back(p - s.begin(), xxHash64(StringRef(p, size)), live);
p += size;
} while (p != end);
} else {
do {
size_t size = findNull(StringRef(p, end - p), entSize) + entSize;
pieces.emplace_back(p - s.begin(), xxHash64(StringRef(p, size)), live);
p += size;
} while (p != end);
}
}
@ -1428,7 +1428,7 @@ void MergeInputSection::splitIntoPieces() {
assert(pieces.empty());
if (flags & SHF_STRINGS)
splitStrings(data(), entsize);
splitStrings(toStringRef(data()), entsize);
else
splitNonStrings(data(), entsize);
}

View File

@ -293,7 +293,7 @@ public:
SyntheticSection *getParent() const;
private:
void splitStrings(ArrayRef<uint8_t> a, size_t size);
void splitStrings(StringRef s, size_t size);
void splitNonStrings(ArrayRef<uint8_t> a, size_t size);
};