Skip to content

Commit

Permalink
[lld-macho][nfc] Move ICF-specific logic into ICF.cpp
Browse files Browse the repository at this point in the history
This mirrors the code organization in `lld/ELF`.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D120378
  • Loading branch information
int3 committed Feb 23, 2022
1 parent 03dff12 commit 8386eb2
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 47 deletions.
12 changes: 9 additions & 3 deletions lld/MachO/ICF.cpp
Expand Up @@ -15,6 +15,7 @@
#include "lld/Common/CommonLinkerContext.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/xxhash.h"

#include <atomic>

Expand Down Expand Up @@ -361,7 +362,8 @@ void macho::foldIdenticalSections() {
for (ConcatInputSection *isec : inputSections) {
// FIXME: consider non-code __text sections as hashable?
bool isHashable = (isCodeSection(isec) || isCfStringSection(isec)) &&
!isec->shouldOmitFromOutput() && isec->isHashableForICF();
!isec->shouldOmitFromOutput() &&
sectionType(isec->getFlags()) == MachO::S_REGULAR;
if (isHashable) {
hashable.push_back(isec);
for (Defined *d : isec->symbols)
Expand All @@ -371,8 +373,12 @@ void macho::foldIdenticalSections() {
isec->icfEqClass[0] = ++icfUniqueID;
}
}
parallelForEach(hashable,
[](ConcatInputSection *isec) { isec->hashForICF(); });
parallelForEach(hashable, [](ConcatInputSection *isec) {
assert(isec->icfEqClass[0] == 0); // don't overwrite a unique ID!
// Turn-on the top bit to guarantee that valid hashes have no collisions
// with the small-integer unique IDs for ICF-ineligible sections
isec->icfEqClass[0] = xxHash64(isec->data) | (1ull << 63);
});
// Now that every input section is either hashed or marked as unique, run the
// segregation algorithm to detect foldable subsections.
ICF(hashable).run();
Expand Down
42 changes: 0 additions & 42 deletions lld/MachO/InputSection.cpp
Expand Up @@ -77,48 +77,6 @@ std::string InputSection::getLocation(uint64_t off) const {
.str();
}

// ICF needs to hash any section that might potentially be duplicated so
// that it can match on content rather than identity.
bool ConcatInputSection::isHashableForICF() const {
switch (sectionType(getFlags())) {
case S_REGULAR:
return true;
case S_CSTRING_LITERALS:
case S_4BYTE_LITERALS:
case S_8BYTE_LITERALS:
case S_16BYTE_LITERALS:
case S_LITERAL_POINTERS:
llvm_unreachable("found unexpected literal type in ConcatInputSection");
case S_ZEROFILL:
case S_GB_ZEROFILL:
case S_NON_LAZY_SYMBOL_POINTERS:
case S_LAZY_SYMBOL_POINTERS:
case S_SYMBOL_STUBS:
case S_MOD_INIT_FUNC_POINTERS:
case S_MOD_TERM_FUNC_POINTERS:
case S_COALESCED:
case S_INTERPOSING:
case S_DTRACE_DOF:
case S_LAZY_DYLIB_SYMBOL_POINTERS:
case S_THREAD_LOCAL_REGULAR:
case S_THREAD_LOCAL_ZEROFILL:
case S_THREAD_LOCAL_VARIABLES:
case S_THREAD_LOCAL_VARIABLE_POINTERS:
case S_THREAD_LOCAL_INIT_FUNCTION_POINTERS:
return false;
default:
llvm_unreachable("Section type");
}
}

void ConcatInputSection::hashForICF() {
assert(data.data()); // zeroFill section data has nullptr with non-zero size
assert(icfEqClass[0] == 0); // don't overwrite a unique ID!
// Turn-on the top bit to guarantee that valid hashes have no collisions
// with the small-integer unique IDs for ICF-ineligible sections
icfEqClass[0] = xxHash64(data) | (1ull << 63);
}

void ConcatInputSection::foldIdentical(ConcatInputSection *copy) {
align = std::max(align, copy->align);
copy->live = false;
Expand Down
2 changes: 0 additions & 2 deletions lld/MachO/InputSection.h
Expand Up @@ -100,8 +100,6 @@ class ConcatInputSection final : public InputSection {
void markLive(uint64_t off) override { live = true; }
bool isCoalescedWeak() const { return wasCoalesced && symbols.empty(); }
bool shouldOmitFromOutput() const { return !live || isCoalescedWeak(); }
bool isHashableForICF() const;
void hashForICF();
void writeTo(uint8_t *buf);

void foldIdentical(ConcatInputSection *redundant);
Expand Down

0 comments on commit 8386eb2

Please sign in to comment.