Skip to content

Commit

Permalink
COFF: Do not create SectionChunks for discarded comdat sections.
Browse files Browse the repository at this point in the history
With this change, instead of creating a SectionChunk for each section
in the object file, we only create them when we encounter a prevailing
comdat section.

Also change how symbol resolution occurs between comdat symbols. Now
only the comdat leader participates in comdat resolution, and not any
other external associated symbols. This is more in line with how COFF
semantics are defined, and should allow for a more straightforward
implementation of non-ANY comdat types.

On my machine, this change reduces our runtime linking a release
build of chrome_child.dll with /nopdb from 5.65s to 4.54s (median of
50 runs).

Differential Revision: https://reviews.llvm.org/D40238

llvm-svn: 319090
  • Loading branch information
pcc committed Nov 27, 2017
1 parent 1f34379 commit 3f2921f
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 164 deletions.
11 changes: 2 additions & 9 deletions lld/COFF/Chunks.cpp
Expand Up @@ -38,9 +38,6 @@ SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)

Alignment = Header->getAlignment();

// Chunks may be discarded during comdat merging.
Discarded = false;

// If linker GC is disabled, every chunk starts out alive. If linker GC is
// enabled, treat non-comdat sections as roots. Generally optimized object
// files will be built with -ffunction-sections or /Gy, so most things worth
Expand Down Expand Up @@ -362,12 +359,8 @@ bool SectionChunk::isCOMDAT() const {
void SectionChunk::printDiscardedMessage() const {
// Removed by dead-stripping. If it's removed by ICF, ICF already
// printed out the name, so don't repeat that here.
if (Sym && this == Repl) {
if (Discarded)
message("Discarded comdat symbol " + Sym->getName());
else if (!Live)
message("Discarded " + Sym->getName());
}
if (Sym && this == Repl)
message("Discarded " + Sym->getName());
}

StringRef SectionChunk::getDebugName() {
Expand Down
21 changes: 5 additions & 16 deletions lld/COFF/Chunks.h
Expand Up @@ -159,10 +159,9 @@ class SectionChunk final : public Chunk {
void addAssociative(SectionChunk *Child);

StringRef getDebugName() override;
void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; }

// Returns true if the chunk was not dropped by GC or COMDAT deduplication.
bool isLive() { return Live && !Discarded; }
// Returns true if the chunk was not dropped by GC.
bool isLive() { return Live; }

// Used by the garbage collector.
void markLive() {
Expand All @@ -171,13 +170,6 @@ class SectionChunk final : public Chunk {
Live = true;
}

// Returns true if this chunk was dropped by COMDAT deduplication.
bool isDiscarded() const { return Discarded; }

// Used by the SymbolTable when discarding unused comdat sections. This is
// redundant when GC is enabled, as all comdat sections will start out dead.
void markDiscarded() { Discarded = true; }

// True if this is a codeview debug info chunk. These will not be laid out in
// the image. Instead they will end up in the PDB, if one is requested.
bool isCodeView() const {
Expand Down Expand Up @@ -213,24 +205,21 @@ class SectionChunk final : public Chunk {
// The file that this chunk was created from.
ObjFile *File;

// The COMDAT leader symbol if this is a COMDAT chunk.
DefinedRegular *Sym = nullptr;

private:
StringRef SectionName;
std::vector<SectionChunk *> AssocChildren;
llvm::iterator_range<const coff_relocation *> Relocs;
size_t NumRelocs;

// True if this chunk was discarded because it was a duplicate comdat section.
bool Discarded;

// Used by the garbage collector.
bool Live;

// Used for ICF (Identical COMDAT Folding)
void replace(SectionChunk *Other);
uint32_t Class[2] = {0, 0};

// Sym points to a section symbol if this is a COMDAT chunk.
DefinedRegular *Sym = nullptr;
};

// A chunk for common symbols. Common chunks don't have actual data.
Expand Down

0 comments on commit 3f2921f

Please sign in to comment.