[PATCH] D15564: [ELF] - Optimize .eh_frame section: remove CIE if all FDEs referencing it were removed.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 30 03:44:21 PST 2015


This revision was automatically updated to reflect the committed changes.
Closed by commit rL256638: [ELF] - Optimize .eh_frame section: remove CIE if all FDEs referencing it… (authored by grimar).

Changed prior to commit:
  http://reviews.llvm.org/D15564?vs=42991&id=43780#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D15564

Files:
  lld/trunk/ELF/OutputSections.cpp
  lld/trunk/test/ELF/eh-frame-opt.s

Index: lld/trunk/ELF/OutputSections.cpp
===================================================================
--- lld/trunk/ELF/OutputSections.cpp
+++ lld/trunk/ELF/OutputSections.cpp
@@ -947,7 +947,8 @@
   auto RelI = Rels.begin();
   auto RelE = Rels.end();
 
-  DenseMap<unsigned, unsigned> OffsetToIndex;
+  // Maps offset to Index/Length pair.
+  DenseMap<unsigned, std::pair<unsigned, uint32_t>> OffsetToData;
   while (!D.empty()) {
     unsigned Index = S->Offsets.size();
     S->Offsets.push_back(std::make_pair(Offset, -1));
@@ -974,21 +975,24 @@
 
       std::pair<StringRef, StringRef> CieInfo(Entry, Personality);
       auto P = CieMap.insert(std::make_pair(CieInfo, Cies.size()));
-      if (P.second) {
+      if (P.second)
         Cies.push_back(C);
-        this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t));
-      }
-      OffsetToIndex[Offset] = P.first->second;
+      OffsetToData[Offset] = std::make_pair(P.first->second, Length);
     } else {
       if (!HasReloc)
         error("FDE doesn't reference another section");
       InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI);
       if (Target != &InputSection<ELFT>::Discarded && Target->isLive()) {
         uint32_t CieOffset = Offset + 4 - ID;
-        auto I = OffsetToIndex.find(CieOffset);
-        if (I == OffsetToIndex.end())
+        auto I = OffsetToData.find(CieOffset);
+        if (I == OffsetToData.end())
           error("Invalid CIE reference");
-        Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index));
+        std::pair<unsigned, uint32_t> &IndLen = I->second;
+        Cie<ELFT> &Cie = Cies[IndLen.first];
+        if (Cie.Fdes.empty())
+          this->Header.sh_size +=
+              RoundUpToAlignment(IndLen.second, sizeof(uintX_t));
+        Cie.Fdes.push_back(EHRegion<ELFT>(S, Index));
         this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t));
       }
     }
Index: lld/trunk/test/ELF/eh-frame-opt.s
===================================================================
--- lld/trunk/test/ELF/eh-frame-opt.s
+++ lld/trunk/test/ELF/eh-frame-opt.s
@@ -0,0 +1,39 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld --gc-sections %t.o -o %t
+// RUN: llvm-readobj -s -section-data %t | FileCheck %s
+
+// Here we check that if all FDEs referencing a CIE
+// were removed, CIE is also removed.
+// CHECK:        Section {
+// CHECK:        Index:
+// CHECK:        Name: .eh_frame
+// CHECK-NEXT:   Type: SHT_X86_64_UNWIND
+// CHECK-NEXT:   Flags [
+// CHECK-NEXT:     SHF_ALLOC
+// CHECK-NEXT:   ]
+// CHECK-NEXT:   Address: 0x10120
+// CHECK-NEXT:   Offset: 0x120
+// CHECK-NEXT:   Size: 0
+// CHECK-NEXT:   Link: 0
+// CHECK-NEXT:   Info: 0
+// CHECK-NEXT:   AddressAlignment: 8
+// CHECK-NEXT:   EntrySize: 0
+// CHECK-NEXT:   SectionData (
+// CHECK-NEXT:   )
+// CHECK-NEXT: }
+
+.section foo,"ax", at progbits
+.cfi_startproc
+ nop
+.cfi_endproc
+
+.section bar,"ax", at progbits
+.cfi_startproc
+ nop
+ nop
+.cfi_endproc
+
+.text
+.globl _start;
+_start:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15564.43780.patch
Type: text/x-patch
Size: 3067 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151230/0c91269c/attachment.bin>


More information about the llvm-commits mailing list