[lld] r315384 - Handle input section liveness only in MarkLive.cpp.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 10 15:59:32 PDT 2017
Author: ruiu
Date: Tue Oct 10 15:59:32 2017
New Revision: 315384
URL: http://llvm.org/viewvc/llvm-project?rev=315384&view=rev
Log:
Handle input section liveness only in MarkLive.cpp.
The condition whether a section is alive or not by default
is becoming increasingly complex, so the decision of garbage
collection is spreading over InputSection.h and MarkLive.cpp,
which is not a good state.
This moves the code to MarkLive.cpp, to keep the file the central
place to make decisions about garbage collection.
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/MarkLive.cpp
lld/trunk/ELF/SyntheticSections.cpp
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=315384&r1=315383&r2=315384&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Oct 10 15:59:32 2017
@@ -1106,8 +1106,7 @@ template <class ELFT> void LinkerDriver:
// Do size optimizations: garbage collection, merging of SHF_MERGE sections
// and identical code folding.
- if (Config->GcSections)
- markLive<ELFT>();
+ markLive<ELFT>();
decompressAndMergeSections();
if (Config->ICF)
doIcf<ELFT>();
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=315384&r1=315383&r2=315384&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Tue Oct 10 15:59:32 2017
@@ -482,20 +482,6 @@ InputSectionBase *ObjFile<ELFT>::createI
if (Config->Strip != StripPolicy::None && Name.startswith(".debug"))
return &InputSection::Discarded;
- // If -gdb-index is given, LLD creates .gdb_index section, and that
- // section serves the same purpose as .debug_gnu_pub{names,types} sections.
- // If that's the case, we want to eliminate .debug_gnu_pub{names,types}
- // because they are redundant and can waste large amount of disk space
- // (for example, they are about 400 MiB in total for a clang debug build.)
- // We still create the section and mark it dead so that the gdb index code
- // can use the InputSection to access the data.
- if (Config->GdbIndex &&
- (Name == ".debug_gnu_pubnames" || Name == ".debug_gnu_pubtypes")) {
- auto *Ret = make<InputSection>(this, &Sec, Name);
- Script->discard({Ret});
- return Ret;
- }
-
// The linkonce feature is a sort of proto-comdat. Some glibc i386 object
// files contain definitions of symbol "__x86.get_pc_thunk.bx" in linkonce
// sections. Drop those sections to avoid duplicate symbol errors.
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=315384&r1=315383&r2=315384&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Oct 10 15:59:32 2017
@@ -76,22 +76,6 @@ static ArrayRef<uint8_t> getSectionConte
return check(File->getObj().getSectionContents(Hdr));
}
-// Return true if a section with given section flags is live (will never be
-// GCed) by default. If a section can be GCed, this function returns false.
-static bool isLiveByDefault(uint64_t Flags, uint32_t Type) {
- // If GC is enabled, all memory-mapped sections are subject of GC.
- if (!Config->GcSections)
- return true;
- if (Flags & SHF_ALLOC)
- return false;
-
- // Besides that, relocation sections can also be GCed because their
- // relocation target sections may be GCed. This doesn't really matter
- // in most cases because the linker usually consumes relocation
- // sections instead of emitting them, but -emit-reloc needs this.
- return Type != SHT_REL && Type != SHT_RELA;
-}
-
InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
uint32_t Type, uint64_t Entsize,
uint32_t Link, uint32_t Info,
@@ -100,7 +84,6 @@ InputSectionBase::InputSectionBase(Input
: SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
Link),
File(File), Data(Data), Repl(this) {
- Live = isLiveByDefault(Flags, Type);
Assigned = false;
NumRelocations = 0;
AreRelocsRela = false;
Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=315384&r1=315383&r2=315384&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Tue Oct 10 15:59:32 2017
@@ -186,7 +186,7 @@ template <class ELFT> static bool isRese
// This is the main function of the garbage collector.
// Starting from GC-root sections, this function visits all reachable
// sections to set their "Live" bits.
-template <class ELFT> void elf::markLive() {
+template <class ELFT> static void doGcSections() {
SmallVector<InputSection *, 256> Q;
CNamedSections.clear();
@@ -261,6 +261,42 @@ template <class ELFT> void elf::markLive
forEachSuccessor<ELFT>(*Q.pop_back_val(), Enqueue);
}
+// Before calling this function, Live bits are off for all
+// input sections. This function make some or all of them on
+// so that they are emitted to the output file.
+template <class ELFT> void elf::markLive() {
+ // If -gc-sections is missing, no sections are removed.
+ if (!Config->GcSections) {
+ for (InputSectionBase *Sec : InputSections)
+ Sec->Live = true;
+ return;
+ }
+
+ // The -gc-sections option works only for SHF_ALLOC sections
+ // (sections that are memory-mapped at runtime). So we can
+ // unconditionally make non-SHF_ALLOC sections alive.
+ //
+ // Non SHF_ALLOC sections are not removed even if they are
+ // unreachable through relocations because reachability is not
+ // a good signal whether they are garbage or not (e.g. there is
+ // usually no section referring to a .comment section, but we
+ // want to keep it.)
+ //
+ // Note on SHF_REL{,A}: Such sections reach here only when -r
+ // or -emit-reloc were given. And they are subject of garbage
+ // collection because, if we remove a text section, we also
+ // remove its relocation section.
+ for (InputSectionBase *Sec : InputSections) {
+ bool IsAlloc = (Sec->Flags & SHF_ALLOC);
+ bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA);
+ if (!IsAlloc && !IsRel)
+ Sec->Live = true;
+ }
+
+ // Follow the graph to mark all live sections.
+ doGcSections<ELFT>();
+}
+
template void elf::markLive<ELF32LE>();
template void elf::markLive<ELF32BE>();
template void elf::markLive<ELF64LE>();
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=315384&r1=315383&r2=315384&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Oct 10 15:59:32 2017
@@ -1831,6 +1831,7 @@ std::vector<std::vector<uint32_t>> GdbIn
}
template <class ELFT> GdbIndexSection *elf::createGdbIndex() {
+ // Gather debug info to create a .gdb_index section.
std::vector<InputSection *> Sections = getDebugInfoSections();
std::vector<GdbIndexChunk> Chunks(Sections.size());
@@ -1844,6 +1845,14 @@ template <class ELFT> GdbIndexSection *e
Chunks[I].NamesAndTypes = readPubNamesAndTypes(Dwarf);
});
+ // .debug_gnu_pub{names,types} are useless in executables.
+ // They are present in input object files solely for creating
+ // a .gdb_index. So we can remove it from the output.
+ for (InputSectionBase *S : InputSections)
+ if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes")
+ S->Live = false;
+
+ // Create a .gdb_index and returns it.
return make<GdbIndexSection>(std::move(Chunks));
}
More information about the llvm-commits
mailing list