[lld] r246511 - Sort common symbols by alignment.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 31 17:16:39 PDT 2015


Author: rafael
Date: Mon Aug 31 19:16:38 2015
New Revision: 246511

URL: http://llvm.org/viewvc/llvm-project?rev=246511&view=rev
Log:
Sort common symbols by alignment.

Modified:
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/common.s

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=246511&r1=246510&r2=246511&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Aug 31 19:16:38 2015
@@ -408,6 +408,12 @@ template <bool Is64Bits> struct DenseMap
 };
 }
 
+template <class ELFT>
+static bool cmpAlign(const DefinedCommon<ELFT> *A,
+                     const DefinedCommon<ELFT> *B) {
+  return A->Sym.st_value > B->Sym.st_value;
+}
+
 // Create output section objects and add them to OutputSections.
 template <class ELFT> void Writer<ELFT>::createSections() {
   SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT> *> Map;
@@ -438,19 +444,25 @@ template <class ELFT> void Writer<ELFT>:
 
   SymTable.BSSSec = getSection(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
   OutputSection<ELFT> *BSSSec = SymTable.BSSSec;
-  uintX_t Off = BSSSec->getSize();
   // FIXME: Try to avoid the extra walk over all global symbols.
+  std::vector<DefinedCommon<ELFT> *> CommonSymbols;
   for (auto &P : Symtab.getSymbols()) {
     SymbolBody *Body = P.second->Body;
-    auto *C = dyn_cast<DefinedCommon<ELFT>>(Body);
-    if (!C)
-      continue;
+    if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body))
+      CommonSymbols.push_back(C);
+  }
+
+  // Sort the common symbols by alignment as an heuristic to pack them better.
+  std::stable_sort(CommonSymbols.begin(), CommonSymbols.end(), cmpAlign<ELFT>);
+  uintX_t Off = BSSSec->getSize();
+  for (DefinedCommon<ELFT> *C : CommonSymbols) {
     const Elf_Sym &Sym = C->Sym;
     uintX_t Align = Sym.st_value;
     Off = RoundUpToAlignment(Off, Align);
     C->OffsetInBSS = Off;
     Off += Sym.st_size;
   }
+
   BSSSec->setSize(Off);
 }
 

Modified: lld/trunk/test/elf2/common.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/common.s?rev=246511&r1=246510&r2=246511&view=diff
==============================================================================
--- lld/trunk/test/elf2/common.s (original)
+++ lld/trunk/test/elf2/common.s Mon Aug 31 19:16:38 2015
@@ -11,8 +11,18 @@
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT: ]
 // CHECK-NEXT: Address: 0x1000
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 18
 
 
+// CHECK:      Name: sym3
+// CHECK-NEXT: Value: 0x1010
+// CHECK-NEXT: Size: 2
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .bss
+
 // CHECK:      Name: sym2
 // CHECK-NEXT: Value: 0x1008
 // CHECK-NEXT: Size: 8
@@ -35,3 +45,4 @@ _start:
 
 .comm sym1,4,4
 .comm sym2,8,4
+.comm sym3,2,2




More information about the llvm-commits mailing list