[lld] r361657 - [COFF] Replace OutputSection* with uint16_t index in Chunk

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri May 24 11:25:49 PDT 2019


Author: rnk
Date: Fri May 24 11:25:49 2019
New Revision: 361657

URL: http://llvm.org/viewvc/llvm-project?rev=361657&view=rev
Log:
[COFF] Replace OutputSection* with uint16_t index in Chunk

Shaves another 8 bytes off of SectionChunk, the most commonly allocated
type in LLD.

These indices are only valid after we've assigned chunks to output
sections and removed empty sections, so do that in a new pass.

Reviewers: ruiu, aganea

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

Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Chunks.h
    lld/trunk/COFF/PDB.cpp
    lld/trunk/COFF/Writer.cpp
    lld/trunk/test/COFF/strtab-size.s

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=361657&r1=361656&r2=361657&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Fri May 24 11:25:49 2019
@@ -53,7 +53,7 @@ SectionChunk::SectionChunk(ObjFile *F, c
 // 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) <= 104, "SectionChunk grew unexpectedly");
+static_assert(sizeof(SectionChunk) <= 96, "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); }
@@ -858,7 +858,7 @@ uint8_t Baserel::getDefaultType() {
 MergeChunk *MergeChunk::Instances[Log2MaxSectionAlignment + 1] = {};
 
 MergeChunk::MergeChunk(uint32_t Alignment)
-    : Builder(StringTableBuilder::RAW, Alignment) {
+    : Chunk(OtherKind), Builder(StringTableBuilder::RAW, Alignment) {
   setAlignment(Alignment);
 }
 
@@ -886,7 +886,6 @@ void MergeChunk::assignSubsectionRVAs()
     if (!C->Live)
       continue;
     size_t Off = Builder.getOffset(toStringRef(C->getContents()));
-    C->setOutputSection(Out);
     C->setRVA(RVA + Off);
   }
 }

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=361657&r1=361656&r2=361657&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Fri May 24 11:25:49 2019
@@ -103,8 +103,9 @@ public:
 
   // An output section has pointers to chunks in the section, and each
   // chunk has a back pointer to an output section.
-  void setOutputSection(OutputSection *O) { Out = O; }
-  OutputSection *getOutputSection() const { return Out; }
+  void setOutputSectionIdx(uint16_t O) { OSIdx = O; }
+  uint16_t getOutputSectionIdx() const { return OSIdx; }
+  OutputSection *getOutputSection() const;
 
   // Windows-specific.
   // Collect all locations that contain absolute addresses for base relocations.
@@ -125,11 +126,12 @@ protected:
   // value.
   uint8_t P2Align = 0;
 
+  // The output section index for this chunk. The first valid section number is
+  // one.
+  uint16_t OSIdx = 0;
+
   // The RVA of this chunk in the output. The writer sets a value.
   uint32_t RVA = 0;
-
-  // The output section for this chunk.
-  OutputSection *Out = nullptr;
 };
 
 // A chunk corresponding a section of an input file.

Modified: lld/trunk/COFF/PDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/PDB.cpp?rev=361657&r1=361656&r2=361657&view=diff
==============================================================================
--- lld/trunk/COFF/PDB.cpp (original)
+++ lld/trunk/COFF/PDB.cpp Fri May 24 11:25:49 2019
@@ -1030,7 +1030,7 @@ void PDBLinker::mergeSymbolRecords(ObjFi
 static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
                                             SectionChunk &DebugChunk) {
   uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk.getSize());
-  assert(DebugChunk.getOutputSection() == nullptr &&
+  assert(DebugChunk.getOutputSectionIdx() == 0 &&
          "debug sections should not be in output sections");
   DebugChunk.writeTo(Buffer);
   return makeArrayRef(Buffer, DebugChunk.getSize());

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=361657&r1=361656&r2=361657&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Fri May 24 11:25:49 2019
@@ -78,6 +78,14 @@ static_assert(DOSStubSize % 8 == 0, "DOS
 
 static const int NumberOfDataDirectory = 16;
 
+// Global vector of all output sections. After output sections are finalized,
+// this can be indexed by Chunk::getOutputSection.
+static std::vector<OutputSection *> OutputSections;
+
+OutputSection *Chunk::getOutputSection() const {
+  return OSIdx == 0 ? nullptr : OutputSections[OSIdx - 1];
+}
+
 namespace {
 
 class DebugDirectoryChunk : public Chunk {
@@ -192,6 +200,7 @@ private:
   void assignAddresses();
   void finalizeAddresses();
   void removeEmptySections();
+  void assignOutputSectionIndices();
   void createSymbolAndStringTable();
   void openFile(StringRef OutputPath);
   template <typename PEHeaderTy> void writeHeader();
@@ -225,7 +234,6 @@ private:
 
   std::unique_ptr<FileOutputBuffer> &Buffer;
   std::map<PartialSectionKey, PartialSection *> PartialSections;
-  std::vector<OutputSection *> OutputSections;
   std::vector<char> Strtab;
   std::vector<llvm::object::coff_symbol16> OutputSymtab;
   IdataContents Idata;
@@ -284,12 +292,10 @@ void writeResult() { Writer().run(); }
 
 void OutputSection::addChunk(Chunk *C) {
   Chunks.push_back(C);
-  C->setOutputSection(this);
 }
 
 void OutputSection::insertChunkAtStart(Chunk *C) {
   Chunks.insert(Chunks.begin(), C);
-  C->setOutputSection(this);
 }
 
 void OutputSection::setPermissions(uint32_t C) {
@@ -298,8 +304,6 @@ void OutputSection::setPermissions(uint3
 }
 
 void OutputSection::merge(OutputSection *Other) {
-  for (Chunk *C : Other->Chunks)
-    C->setOutputSection(this);
   Chunks.insert(Chunks.end(), Other->Chunks.begin(), Other->Chunks.end());
   Other->Chunks.clear();
   ContribSections.insert(ContribSections.end(), Other->ContribSections.begin(),
@@ -444,7 +448,6 @@ static bool createThunks(OutputSection *
         Chunk *ThunkChunk = Thunk->getChunk();
         ThunkChunk->setRVA(
             ThunkInsertionRVA); // Estimate of where it will be located.
-        ThunkChunk->setOutputSection(OS);
         OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
         ThunkInsertionSpot++;
         ThunksSize += ThunkChunk->getSize();
@@ -595,6 +598,7 @@ void Writer::run() {
   removeUnusedSections();
   finalizeAddresses();
   removeEmptySections();
+  assignOutputSectionIndices();
   setSectionPermissions();
   createSymbolAndStringTable();
 
@@ -1000,9 +1004,26 @@ void Writer::removeEmptySections() {
   OutputSections.erase(
       std::remove_if(OutputSections.begin(), OutputSections.end(), IsEmpty),
       OutputSections.end());
+}
+
+void Writer::assignOutputSectionIndices() {
+  // Assign final output section indices, and assign each chunk to its output
+  // section.
   uint32_t Idx = 1;
-  for (OutputSection *Sec : OutputSections)
-    Sec->SectionIndex = Idx++;
+  for (OutputSection *OS : OutputSections) {
+    OS->SectionIndex = Idx;
+    for (Chunk *C : OS->Chunks)
+      C->setOutputSectionIdx(Idx);
+    ++Idx;
+  }
+
+  // Merge chunks are containers of chunks, so assign those an output section
+  // too.
+  for (MergeChunk *MC : MergeChunk::Instances)
+    if (MC)
+      for (SectionChunk *SC : MC->Sections)
+        if (SC && SC->Live)
+          SC->setOutputSectionIdx(MC->getOutputSectionIdx());
 }
 
 size_t Writer::addEntryToStringTable(StringRef Str) {
@@ -1463,9 +1484,9 @@ static void maybeAddAddressTakenFunction
     // section.
     auto *D = cast<DefinedRegular>(S);
     if (D->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
-      Chunk *RefChunk = D->getChunk();
-      OutputSection *OS = RefChunk ? RefChunk->getOutputSection() : nullptr;
-      if (OS && OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)
+      SectionChunk *SC = dyn_cast<SectionChunk>(D->getChunk());
+      if (SC && SC->Live &&
+          SC->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)
         addSymbolToRVASet(AddressTakenSyms, D);
     }
     break;
@@ -1744,8 +1765,9 @@ void Writer::sortExceptionTable() {
     return;
   // We assume .pdata contains function table entries only.
   auto BufAddr = [&](Chunk *C) {
-    return Buffer->getBufferStart() + C->getOutputSection()->getFileOff() +
-           C->getRVA() - C->getOutputSection()->getRVA();
+    OutputSection *OS = C->getOutputSection();
+    return Buffer->getBufferStart() + OS->getFileOff() + C->getRVA() -
+           OS->getRVA();
   };
   uint8_t *Begin = BufAddr(FirstPdata);
   uint8_t *End = BufAddr(LastPdata) + LastPdata->getSize();

Modified: lld/trunk/test/COFF/strtab-size.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/strtab-size.s?rev=361657&r1=361656&r2=361657&view=diff
==============================================================================
--- lld/trunk/test/COFF/strtab-size.s (original)
+++ lld/trunk/test/COFF/strtab-size.s Fri May 24 11:25:49 2019
@@ -13,7 +13,7 @@
 # or disk full, cannot seek to 0x1602").
 
 # RUN: llvm-readobj --file-headers %t.exe | FileCheck %s
-# CHECK: SymbolCount: 199
+# CHECK: SymbolCount: 197
 
 .global main
 .text




More information about the llvm-commits mailing list