[PATCH] D66719: [ELF] Do not ICF two sections with different output sections when there is a linker script

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 25 09:54:31 PDT 2019


MaskRay created this revision.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
MaskRay abandoned this revision.
MaskRay added a comment.

D66717 <https://reviews.llvm.org/D66717> should be better


This complements D47241 <https://reviews.llvm.org/D47241> for the non-linker-script (getOutputSectionName) case.

This implements the unfold approach as briefed at https://reviews.llvm.org/D54422#1302994

  // Do not ICF fold input sections between output sections. If the output
  // sections of sec and the InputSection it gets folded into are different,
  // unfold it. sec->repl may have increased alignment or be have moved to the
  // main partition, but that does not matter.

--print-icf-sections is not handled.


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D66719

Files:
  ELF/ICF.cpp
  ELF/LinkerScript.cpp


Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -378,7 +378,7 @@
     size_t sizeBefore = ret.size();
 
     for (InputSectionBase *sec : inputSections) {
-      if (!sec->isLive() || sec->assigned)
+      if (sec->assigned || (!sec->isLive() && sec->repl == sec))
         continue;
 
       // For -emit-relocs we have to ignore entries like
@@ -421,8 +421,11 @@
     if (s == mainPart->hashTab)
       mainPart->hashTab = nullptr;
 
-    s->assigned = false;
+    // Entirely discarded. s->repl != s indicates a section that can be unfolded
+    // later.
     s->markDead();
+    s->repl = s;
+
     discard(s->dependentSections);
   }
 }
@@ -461,6 +464,7 @@
   ctx = deleter.get();
   ctx->outSec = aether;
 
+  DenseMap<OutputSection *, std::vector<InputSection *>> inputs;
   size_t i = 0;
   // Add input sections to output sections.
   for (BaseCommand *base : sectionCommands) {
@@ -510,9 +514,9 @@
           s->alignment = subalign;
       }
 
-      // Add input sections to an output section.
-      for (InputSection *s : v)
-        sec->addSection(s);
+      for (InputSection *&s : v)
+        s->parent = sec;
+      inputs[sec] = std::move(v);
 
       sec->sectionIndex = i++;
       if (sec->noload)
@@ -521,6 +525,28 @@
         sec->flags &= ~(uint64_t)SHF_ALLOC;
     }
   }
+
+  // Do not ICF fold input sections between output sections. If the output
+  // sections of sec and the InputSection it gets folded into are different,
+  // unfold it. sec->repl may have increased alignment or be have moved to the
+  // main partition, but that does not matter.
+  for (auto &it : inputs)
+    for (InputSection *s : it.second)
+      if (s->repl != s && cast<InputSection>(s->repl)->getParent() != s->getParent()) {
+        s->repl = s;
+        s->markLive();
+        for (InputSection *dependent : s->dependentSections)
+          dependent->markLive();
+      }
+
+  // Delete garbage-collected or folded input sections.
+  for (auto &it : inputs) {
+    OutputSection *sec = it.first;
+    for (InputSection *&s : it.second)
+      if (s->isLive())
+        sec->addSection(s);
+  }
+
   ctx = nullptr;
 }
 
Index: ELF/ICF.cpp
===================================================================
--- ELF/ICF.cpp
+++ ELF/ICF.cpp
@@ -303,10 +303,10 @@
       a->getSize() != b->getSize() || a->data() != b->data())
     return false;
 
-  // If two sections have different output sections, we cannot merge them.
-  // FIXME: This doesn't do the right thing in the case where there is a linker
-  // script. We probably need to move output section assignment before ICF to
-  // get the correct behaviour here.
+  // If two sections have different output sections, we cannot merge them. When
+  // there is a linker script, getOutputSectionName may be inaccurate, sections
+  // going into different output sections may get folded but they will be
+  // unfolded in LinkerScript::processSectionCommands.
   if (getOutputSectionName(a) != getOutputSectionName(b))
     return false;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66719.217051.patch
Type: text/x-patch
Size: 3110 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190825/8f327eb0/attachment-0001.bin>


More information about the llvm-commits mailing list