[lld] r357535 - [COFF] Reduce the size of Chunk and SectionChunk, NFC
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 2 15:11:58 PDT 2019
Author: rnk
Date: Tue Apr 2 15:11:58 2019
New Revision: 357535
URL: http://llvm.org/viewvc/llvm-project?rev=357535&view=rev
Log:
[COFF] Reduce the size of Chunk and SectionChunk, NFC
Summary:
Reorder the fields in both to use padding more efficiently, and add more
comments on the purpose of the fields.
Replace `std::vector<SectionChunk*> AssociativeChildren` with a
singly-linked list. This avoids the separate vector allocation to list
associative children, and shrinks the 3 pointers used for the typically
empty vector down to 1.
In the end, this reduces the sum of heap allocations used to link
browser_tests.exe with NO PDB by 13.10%, going from 2,248,728 KB to
1,954,071 KB of heap. These numbers exclude memory mapped files, which
are of course a significant factor in LLD's memory usage.
Reviewers: ruiu, mstorsjo, aganea
Subscribers: jdoerfert, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59797
Modified:
lld/trunk/COFF/Chunks.cpp
lld/trunk/COFF/Chunks.h
lld/trunk/COFF/ICF.cpp
lld/trunk/COFF/MarkLive.cpp
Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=357535&r1=357534&r2=357535&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Tue Apr 2 15:11:58 2019
@@ -30,8 +30,8 @@ namespace lld {
namespace coff {
SectionChunk::SectionChunk(ObjFile *F, const coff_section *H)
- : Chunk(SectionKind), Repl(this), Header(H), File(F),
- Relocs(File->getCOFFObj()->getRelocations(Header)) {
+ : Chunk(SectionKind), File(F), Header(H),
+ Relocs(File->getCOFFObj()->getRelocations(Header)), Repl(this) {
// Initialize SectionName.
File->getCOFFObj()->getSectionName(Header, SectionName);
@@ -44,6 +44,11 @@ SectionChunk::SectionChunk(ObjFile *F, c
Live = !Config->DoGC || !isCOMDAT();
}
+// SectionChunk is one of the most frequently allocated classes, so it is
+// important to keep it as compact as possible. As of this writing, the number
+// below is the size of this class on x64 platforms.
+static_assert(sizeof(SectionChunk) <= 128, "SectionChunk grew unexpectedly");
+
static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
@@ -394,7 +399,11 @@ void SectionChunk::writeTo(uint8_t *Buf)
}
void SectionChunk::addAssociative(SectionChunk *Child) {
- AssocChildren.push_back(Child);
+ // Insert this child at the head of the list.
+ assert(Child->AssocChildren == nullptr &&
+ "associated sections cannot have their own associated children");
+ Child->AssocChildren = AssocChildren;
+ AssocChildren = Child;
}
static uint8_t getBaserelType(const coff_relocation &Rel) {
Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=357535&r1=357534&r2=357535&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Tue Apr 2 15:11:58 2019
@@ -50,7 +50,7 @@ const uint32_t TypeMask = 0x000000E0;
// doesn't even have actual data (if common or bss).
class Chunk {
public:
- enum Kind { SectionKind, OtherKind };
+ enum Kind : uint8_t { SectionKind, OtherKind };
Kind kind() const { return ChunkKind; }
virtual ~Chunk() = default;
@@ -107,6 +107,12 @@ protected:
Chunk(Kind K = OtherKind) : ChunkKind(K) {}
const Kind ChunkKind;
+public:
+ // Whether this section needs to be kept distinct from other sections during
+ // ICF. This is set by the driver using address-significance tables.
+ bool KeepUnique = false;
+
+protected:
// The RVA of this chunk in the output. The writer sets a value.
uint64_t RVA = 0;
@@ -116,10 +122,6 @@ protected:
public:
// The offset from beginning of the output section. The writer sets a value.
uint64_t OutputSectionOff = 0;
-
- // Whether this section needs to be kept distinct from other sections during
- // ICF. This is set by the driver using address-significance tables.
- bool KeepUnique = false;
};
// A chunk corresponding a section of an input file.
@@ -192,8 +194,34 @@ public:
symbol_iterator(File, Relocs.end()));
}
+ // Single linked list iterator for associated comdat children.
+ class AssociatedIterator
+ : public llvm::iterator_facade_base<
+ AssociatedIterator, std::forward_iterator_tag, SectionChunk> {
+ public:
+ AssociatedIterator() = default;
+ AssociatedIterator(SectionChunk *Head) : Cur(Head) {}
+ AssociatedIterator &operator=(const AssociatedIterator &R) {
+ Cur = R.Cur;
+ return *this;
+ }
+ bool operator==(const AssociatedIterator &R) const { return Cur == R.Cur; }
+ const SectionChunk &operator*() const { return *Cur; }
+ SectionChunk &operator*() { return *Cur; }
+ AssociatedIterator &operator++() {
+ Cur = Cur->AssocChildren;
+ return *this;
+ }
+
+ private:
+ SectionChunk *Cur = nullptr;
+ };
+
// Allow iteration over the associated child chunks for this section.
- ArrayRef<SectionChunk *> children() const { return AssocChildren; }
+ llvm::iterator_range<AssociatedIterator> children() const {
+ return llvm::make_range(AssociatedIterator(AssocChildren),
+ AssociatedIterator(nullptr));
+ }
// The section ID this chunk belongs to in its Obj.
uint32_t getSectionNumber() const;
@@ -208,35 +236,37 @@ public:
bool isHotPatchable() const override { return File->HotPatchable; }
- // A pointer pointing to a replacement for this chunk.
- // Initially it points to "this" object. If this chunk is merged
- // with other chunk by ICF, it points to another chunk,
- // and this chunk is considered as dead.
- SectionChunk *Repl;
-
- // The CRC of the contents as described in the COFF spec 4.5.5.
- // Auxiliary Format 5: Section Definitions. Used for ICF.
- uint32_t Checksum = 0;
-
- const coff_section *Header;
-
// The file that this chunk was created from.
ObjFile *File;
+ // Pointer to the COFF section header in the input file.
+ const coff_section *Header;
+
// The COMDAT leader symbol if this is a COMDAT chunk.
DefinedRegular *Sym = nullptr;
- // The COMDAT selection if this is a COMDAT chunk.
- llvm::COFF::COMDATType Selection = (llvm::COFF::COMDATType)0;
-
+ // Relocations for this section.
ArrayRef<coff_relocation> Relocs;
+ // The CRC of the contents as described in the COFF spec 4.5.5.
+ // Auxiliary Format 5: Section Definitions. Used for ICF.
+ uint32_t Checksum = 0;
+
// Used by the garbage collector.
bool Live;
+ // The COMDAT selection if this is a COMDAT chunk.
+ llvm::COFF::COMDATType Selection = (llvm::COFF::COMDATType)0;
+
+ // A pointer pointing to a replacement for this chunk.
+ // Initially it points to "this" object. If this chunk is merged
+ // with other chunk by ICF, it points to another chunk,
+ // and this chunk is considered as dead.
+ SectionChunk *Repl;
+
private:
StringRef SectionName;
- std::vector<SectionChunk *> AssocChildren;
+ SectionChunk *AssocChildren = nullptr;
// Used for ICF (Identical COMDAT Folding)
void replace(SectionChunk *Other);
Modified: lld/trunk/COFF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=357535&r1=357534&r2=357535&view=diff
==============================================================================
--- lld/trunk/COFF/ICF.cpp (original)
+++ lld/trunk/COFF/ICF.cpp Tue Apr 2 15:11:58 2019
@@ -129,10 +129,10 @@ void ICF::segregate(size_t Begin, size_t
bool ICF::assocEquals(const SectionChunk *A, const SectionChunk *B) {
auto ChildClasses = [&](const SectionChunk *SC) {
std::vector<uint32_t> Classes;
- for (const SectionChunk *C : SC->children())
- if (!C->SectionName.startswith(".debug") &&
- C->SectionName != ".gfids$y" && C->SectionName != ".gljmp$y")
- Classes.push_back(C->Class[Cnt % 2]);
+ for (const SectionChunk &C : SC->children())
+ if (!C.SectionName.startswith(".debug") &&
+ C.SectionName != ".gfids$y" && C.SectionName != ".gljmp$y")
+ Classes.push_back(C.Class[Cnt % 2]);
return Classes;
};
return ChildClasses(A) == ChildClasses(B);
Modified: lld/trunk/COFF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/MarkLive.cpp?rev=357535&r1=357534&r2=357535&view=diff
==============================================================================
--- lld/trunk/COFF/MarkLive.cpp (original)
+++ lld/trunk/COFF/MarkLive.cpp Tue Apr 2 15:11:58 2019
@@ -64,8 +64,8 @@ void markLive(ArrayRef<Chunk *> Chunks)
AddSym(B);
// Mark associative sections if any.
- for (SectionChunk *C : SC->children())
- Enqueue(C);
+ for (SectionChunk &C : SC->children())
+ Enqueue(&C);
}
}
More information about the llvm-commits
mailing list