Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -1303,9 +1303,10 @@ // Do size optimizations: garbage collection, merging of SHF_MERGE sections // and identical code folding. + decompressSections(); + splitSections(); markLive(); demoteSymbols(); - decompressSections(); mergeSections(); if (Config->ICF) doIcf(); Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -224,10 +224,7 @@ void splitIntoPieces(); // Mark the piece at a given offset live. Used by GC. - void markLiveAt(uint64_t Offset) { - if (this->Flags & llvm::ELF::SHF_ALLOC) - LiveOffsets.insert(Offset); - } + void markLiveAt(uint64_t Offset); // Translate an offset in the input section to an offset in the parent // MergeSyntheticSection. @@ -259,8 +256,6 @@ private: void splitStrings(ArrayRef A, size_t Size); void splitNonStrings(ArrayRef A, size_t Size); - - llvm::DenseSet LiveOffsets; }; struct EhSectionPiece { Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -909,6 +909,10 @@ : InputSectionBase(nullptr, Flags, Type, Entsize, /*Link*/ 0, /*Info*/ 0, /*Alignment*/ Entsize, Data, Name, SectionBase::Merge) {} +void MergeInputSection::markLiveAt(uint64_t Offset) { + getSectionPiece(Offset)->Live = true; +} + // This function is called after we obtain a complete list of input sections // that need to be linked. This is responsible to split section contents // into small chunks for further processing. @@ -926,10 +930,6 @@ OffsetMap.reserve(Pieces.size()); for (size_t I = 0, E = Pieces.size(); I != E; ++I) OffsetMap[Pieces[I].InputOff] = I; - - if (Config->GcSections && (Flags & SHF_ALLOC)) - for (uint32_t Off : LiveOffsets) - getSectionPiece(Off)->Live = true; } template Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -834,6 +834,7 @@ InputSection *createInterpSection(); MergeInputSection *createCommentSection(); void decompressSections(); +void splitSections(); void mergeSections(); Defined *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2536,9 +2536,16 @@ // Debug sections may be compressed by zlib. Decompress if exists. void elf::decompressSections() { + parallelForEach(InputSections, + [](InputSectionBase *Sec) { Sec->maybeDecompress(); }); +} + +void elf::splitSections() { + // splitIntoPieces needs to be called on each MergeInputSection + // before calling finalizeContents(). parallelForEach(InputSections, [](InputSectionBase *Sec) { - if (Sec->Live) - Sec->maybeDecompress(); + if (auto *S = dyn_cast(Sec)) + S->splitIntoPieces(); }); } @@ -2550,13 +2557,6 @@ // that it replaces. It then finalizes each synthetic section in order // to compute an output offset for each piece of each input section. void elf::mergeSections() { - // splitIntoPieces needs to be called on each MergeInputSection - // before calling finalizeContents(). Do that first. - parallelForEach(InputSections, [](InputSectionBase *Sec) { - if (auto *S = dyn_cast(Sec)) - S->splitIntoPieces(); - }); - std::vector MergeSections; for (InputSectionBase *&S : InputSections) { MergeInputSection *MS = dyn_cast(S);