[ELF] Speed up/simplify removeUnusedSyntheticSections. NFC
authorFangrui Song <i@maskray.me>
Mon, 29 Nov 2021 05:07:33 +0000 (21:07 -0800)
committerFangrui Song <i@maskray.me>
Mon, 29 Nov 2021 05:07:34 +0000 (21:07 -0800)
Make one change: when the OutputSection is nullptr (due to /DISCARD/ or garbage
collected BssSection (replaceCommonSymbols)), discard the SyntheticSection as well.

lld/ELF/Writer.cpp

index 42e63ee..77a6626 100644 (file)
@@ -1836,33 +1836,26 @@ static void removeUnusedSyntheticSections() {
                             })
                    .base();
 
-  DenseSet<InputSectionDescription *> isdSet;
   // Mark unused synthetic sections for deletion
-  auto end = std::stable_partition(
-      start, inputSections.end(), [&](InputSectionBase *s) {
-        SyntheticSection *ss = dyn_cast<SyntheticSection>(s);
-        OutputSection *os = ss->getParent();
-        if (!os || ss->isNeeded())
-          return true;
-
-        // If we reach here, then ss is an unused synthetic section and we want
-        // to remove it from the corresponding input section description, and
-        // orphanSections.
-        for (SectionCommand *b : os->commands)
-          if (auto *isd = dyn_cast<InputSectionDescription>(b))
-            isdSet.insert(isd);
-
-        llvm::erase_if(
-            script->orphanSections,
-            [=](const InputSectionBase *isec) { return isec == ss; });
-
-        return false;
-      });
-
+  auto end = std::stable_partition(start, inputSections.end(),
+                                   [&](InputSectionBase *s) {
+                                     auto *sec = cast<SyntheticSection>(s);
+                                     return sec->getParent() && sec->isNeeded();
+                                   });
+
+  // Remove unused synthetic sections from the corresponding input section
+  // description and orphanSections.
   DenseSet<InputSectionBase *> unused(end, inputSections.end());
-  for (auto *isd : isdSet)
-    llvm::erase_if(isd->sections,
-                   [=](InputSection *isec) { return unused.count(isec); });
+  for (auto it = end; it != inputSections.end(); ++it)
+    if (OutputSection *osec = cast<SyntheticSection>(*it)->getParent())
+      for (SectionCommand *cmd : osec->commands)
+        if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
+          llvm::erase_if(isd->sections, [&](InputSection *isec) {
+            return unused.count(isec);
+          });
+  llvm::erase_if(script->orphanSections, [&](const InputSectionBase *sec) {
+    return unused.count(sec);
+  });
 
   // Erase unused synthetic sections.
   inputSections.erase(end, inputSections.end());