[lld] r329117 - Inline initOffsetMap.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 3 14:38:18 PDT 2018


Author: rafael
Date: Tue Apr  3 14:38:18 2018
New Revision: 329117

URL: http://llvm.org/viewvc/llvm-project?rev=329117&view=rev
Log:
Inline initOffsetMap.

In the lld perf builder r328686 had a negative impact in
stalled-cycles-frontend. Somehow that stat is not showing on my
machine, but the attached patch shows an improvement on cache-misses,
which is probably a reasonable proxy.

My working theory is that given a large input the pieces vector is out
of cache by the time initOffsetMap runs.

Both finalizeContents implementation have a convenient location for
initializing the OffsetMap, so this seems the best solution.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/SyntheticSections.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=329117&r1=329116&r2=329117&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Apr  3 14:38:18 2018
@@ -985,12 +985,6 @@ uint64_t MergeInputSection::getOffset(ui
   return Piece.OutputOff + Addend;
 }
 
-void MergeInputSection::initOffsetMap() {
-  OffsetMap.reserve(Pieces.size());
-  for (size_t I = 0; I < Pieces.size(); ++I)
-    OffsetMap[Pieces[I].InputOff] = I;
-}
-
 template InputSection::InputSection(ObjFile<ELF32LE> &, const ELF32LE::Shdr &,
                                     StringRef);
 template InputSection::InputSection(ObjFile<ELF32BE> &, const ELF32BE::Shdr &,

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=329117&r1=329116&r2=329117&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Tue Apr  3 14:38:18 2018
@@ -236,6 +236,7 @@ public:
   // Splittable sections are handled as a sequence of data
   // rather than a single large blob of data.
   std::vector<SectionPiece> Pieces;
+  llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
 
   // Returns I'th piece's data. This function is very hot when
   // string merging is enabled, so we want to inline.
@@ -254,14 +255,11 @@ public:
   }
 
   SyntheticSection *getParent() const;
-  void initOffsetMap();
 
 private:
   void splitStrings(ArrayRef<uint8_t> A, size_t Size);
   void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
 
-  llvm::DenseMap<uint32_t, uint32_t> OffsetMap;
-
   llvm::DenseSet<uint32_t> LiveOffsets;
 };
 

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=329117&r1=329116&r2=329117&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Apr  3 14:38:18 2018
@@ -2438,10 +2438,15 @@ void MergeTailSection::finalizeContents(
   // finalize() fixed tail-optimized strings, so we can now get
   // offsets of strings. Get an offset for each string and save it
   // to a corresponding StringPiece for easy access.
-  for (MergeInputSection *Sec : Sections)
-    for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
-      if (Sec->Pieces[I].Live)
-        Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I));
+  for (MergeInputSection *Sec : Sections) {
+    Sec->OffsetMap.reserve(Sec->Pieces.size());
+    for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
+      SectionPiece &P = Sec->Pieces[I];
+      Sec->OffsetMap[P.InputOff] = I;
+      if (P.Live)
+        P.OutputOff = Builder.getOffset(Sec->getData(I));
+    }
+  }
 }
 
 void MergeNoTailSection::writeTo(uint8_t *Buf) {
@@ -2494,10 +2499,13 @@ void MergeNoTailSection::finalizeContent
   // So far, section pieces have offsets from beginning of shards, but
   // we want offsets from beginning of the whole section. Fix them.
   parallelForEach(Sections, [&](MergeInputSection *Sec) {
-    for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
-      if (Sec->Pieces[I].Live)
-        Sec->Pieces[I].OutputOff +=
-            ShardOffsets[getShardId(Sec->Pieces[I].Hash)];
+    Sec->OffsetMap.reserve(Sec->Pieces.size());
+    for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
+      SectionPiece &P = Sec->Pieces[I];
+      Sec->OffsetMap[P.InputOff] = I;
+      if (P.Live)
+        P.OutputOff += ShardOffsets[getShardId(P.Hash)];
+    }
   });
 }
 
@@ -2573,11 +2581,8 @@ void elf::mergeSections() {
     }
     (*I)->addSection(MS);
   }
-  for (auto *MS : MergeSections) {
+  for (auto *MS : MergeSections)
     MS->finalizeContents();
-    parallelForEach(MS->Sections,
-                    [](MergeInputSection *Sec) { Sec->initOffsetMap(); });
-  }
 
   std::vector<InputSectionBase *> &V = InputSections;
   V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());




More information about the llvm-commits mailing list