[lld] r305176 - ELF: Move section merging before ICF. NFCI.
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 11 17:00:52 PDT 2017
Author: pcc
Date: Sun Jun 11 19:00:51 2017
New Revision: 305176
URL: http://llvm.org/viewvc/llvm-project?rev=305176&view=rev
Log:
ELF: Move section merging before ICF. NFCI.
Differential Revision: https://reviews.llvm.org/D34093
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=305176&r1=305175&r2=305176&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Sun Jun 11 19:00:51 2017
@@ -36,6 +36,7 @@
#include "ScriptParser.h"
#include "Strings.h"
#include "SymbolTable.h"
+#include "SyntheticSections.h"
#include "Target.h"
#include "Threads.h"
#include "Writer.h"
@@ -43,7 +44,6 @@
#include "lld/Driver/Driver.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Object/Decompressor.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Path.h"
@@ -1001,24 +1001,20 @@ template <class ELFT> void LinkerDriver:
for (InputSectionBase *S : F->getSections())
InputSections.push_back(cast<InputSection>(S));
- // Do size optimizations: garbage collection and identical code folding.
+ // This adds a .comment section containing a version string. We have to add it
+ // before decompressAndMergeSections because the .comment section is a
+ // mergeable section.
+ if (!Config->Relocatable)
+ InputSections.push_back(createCommentSection<ELFT>());
+
+ // Do size optimizations: garbage collection, merging of SHF_MERGE sections
+ // and identical code folding.
if (Config->GcSections)
markLive<ELFT>();
+ decompressAndMergeSections();
if (Config->ICF)
doIcf<ELFT>();
- // MergeInputSection::splitIntoPieces needs to be called before
- // any call of MergeInputSection::getOffset. Do that.
- parallelForEach(InputSections.begin(), InputSections.end(),
- [](InputSectionBase *S) {
- if (!S->Live)
- return;
- if (Decompressor::isCompressedELFSection(S->Flags, S->Name))
- S->uncompress();
- if (auto *MS = dyn_cast<MergeInputSection>(S))
- MS->splitIntoPieces();
- });
-
// Write the result to the file.
writeResult<ELFT>();
}
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=305176&r1=305175&r2=305176&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Sun Jun 11 19:00:51 2017
@@ -29,6 +29,7 @@
#include "lld/Config/Version.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
+#include "llvm/Object/Decompressor.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MD5.h"
@@ -2133,7 +2134,6 @@ MergeSyntheticSection::MergeSyntheticSec
Builder(StringTableBuilder::RAW, Alignment) {}
void MergeSyntheticSection::addSection(MergeInputSection *MS) {
- assert(!Finalized);
MS->Parent = this;
Sections.push_back(MS);
}
@@ -2178,9 +2178,6 @@ void MergeSyntheticSection::finalizeNoTa
}
void MergeSyntheticSection::finalizeContents() {
- if (Finalized)
- return;
- Finalized = true;
if (shouldTailMerge())
finalizeTailMerge();
else
@@ -2188,11 +2185,65 @@ void MergeSyntheticSection::finalizeCont
}
size_t MergeSyntheticSection::getSize() const {
- // We should finalize string builder to know the size.
- const_cast<MergeSyntheticSection *>(this)->finalizeContents();
return Builder.getSize();
}
+// This function decompresses compressed sections and scans over the input
+// sections to create mergeable synthetic sections. It removes
+// MergeInputSections from the input section array and adds new synthetic
+// sections at the location of the first input section 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::decompressAndMergeSections() {
+ // splitIntoPieces needs to be called on each MergeInputSection before calling
+ // finalizeContents(). Do that first.
+ parallelForEach(InputSections.begin(), InputSections.end(),
+ [](InputSectionBase *S) {
+ if (!S->Live)
+ return;
+ if (Decompressor::isCompressedELFSection(S->Flags, S->Name))
+ S->uncompress();
+ if (auto *MS = dyn_cast<MergeInputSection>(S))
+ MS->splitIntoPieces();
+ });
+
+ std::vector<MergeSyntheticSection *> MergeSections;
+ for (InputSectionBase *&S : InputSections) {
+ MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
+ if (!MS)
+ continue;
+
+ // We do not want to handle sections that are not alive, so just remove
+ // them instead of trying to merge.
+ if (!MS->Live)
+ continue;
+
+ StringRef OutsecName = getOutputSectionName(MS->Name);
+ uint64_t Flags = MS->Flags & ~(uint64_t)SHF_GROUP;
+ uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize);
+
+ auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
+ return Sec->Name == OutsecName && Sec->Flags == Flags &&
+ Sec->Alignment == Alignment;
+ });
+ if (I == MergeSections.end()) {
+ MergeSyntheticSection *Syn =
+ make<MergeSyntheticSection>(OutsecName, MS->Type, Flags, Alignment);
+ MergeSections.push_back(Syn);
+ I = std::prev(MergeSections.end());
+ S = Syn;
+ } else {
+ S = nullptr;
+ }
+ (*I)->addSection(MS);
+ }
+ for (auto *MS : MergeSections)
+ MS->finalizeContents();
+
+ std::vector<InputSectionBase *> &V = InputSections;
+ V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
+}
+
MipsRldMapSection::MipsRldMapSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
".rld_map") {}
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=305176&r1=305175&r2=305176&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Sun Jun 11 19:00:51 2017
@@ -651,7 +651,6 @@ private:
void finalizeTailMerge();
void finalizeNoTailMerge();
- bool Finalized = false;
llvm::StringTableBuilder Builder;
std::vector<MergeInputSection *> Sections;
};
@@ -748,6 +747,7 @@ private:
template <class ELFT> InputSection *createCommonSection();
InputSection *createInterpSection();
template <class ELFT> MergeInputSection *createCommentSection();
+void decompressAndMergeSections();
SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
uint64_t Size, InputSectionBase *Section);
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=305176&r1=305175&r2=305176&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sun Jun 11 19:00:51 2017
@@ -137,46 +137,6 @@ template <class ELFT> void Writer<ELFT>:
Phdrs.erase(I, Phdrs.end());
}
-// This function scans over the input sections and creates mergeable
-// synthetic sections. It removes MergeInputSections from array and
-// adds new synthetic ones. Each synthetic section is added to the
-// location of the first input section it replaces.
-static void combineMergableSections() {
- std::vector<MergeSyntheticSection *> MergeSections;
- for (InputSectionBase *&S : InputSections) {
- MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
- if (!MS)
- continue;
-
- // We do not want to handle sections that are not alive, so just remove
- // them instead of trying to merge.
- if (!MS->Live)
- continue;
-
- StringRef OutsecName = getOutputSectionName(MS->Name);
- uint64_t Flags = MS->Flags & ~(uint64_t)SHF_GROUP;
- uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize);
-
- auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
- return Sec->Name == OutsecName && Sec->Flags == Flags &&
- Sec->Alignment == Alignment;
- });
- if (I == MergeSections.end()) {
- MergeSyntheticSection *Syn =
- make<MergeSyntheticSection>(OutsecName, MS->Type, Flags, Alignment);
- MergeSections.push_back(Syn);
- I = std::prev(MergeSections.end());
- S = Syn;
- } else {
- S = nullptr;
- }
- (*I)->addSection(MS);
- }
-
- std::vector<InputSectionBase *> &V = InputSections;
- V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
-}
-
template <class ELFT> static void combineEhFrameSections() {
for (InputSectionBase *&S : InputSections) {
EhInputSection *ES = dyn_cast<EhInputSection>(S);
@@ -205,7 +165,6 @@ template <class ELFT> void Writer<ELFT>:
// Create linker-synthesized sections such as .got or .plt.
// Such sections are of type input section.
createSyntheticSections();
- combineMergableSections();
if (!Config->Relocatable)
combineEhFrameSections<ELFT>();
@@ -340,9 +299,6 @@ template <class ELFT> void Writer<ELFT>:
InX::Interp = nullptr;
}
- if (!Config->Relocatable)
- Add(createCommentSection<ELFT>());
-
if (Config->Strip != StripPolicy::All) {
InX::StrTab = make<StringTableSection>(".strtab", false);
InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
More information about the llvm-commits
mailing list