[lld] r251095 - [lld][MachO] Prune unused EH frames.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 22 22:39:16 PDT 2015


Author: lhames
Date: Fri Oct 23 00:39:16 2015
New Revision: 251095

URL: http://llvm.org/viewvc/llvm-project?rev=251095&view=rev
Log:
[lld][MachO] Prune unused EH frames.

Modified:
    lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
    lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml
    lld/trunk/test/mach-o/write-final-sections.yaml

Modified: lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp?rev=251095&r1=251094&r2=251095&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp Fri Oct 23 00:39:16 2015
@@ -310,6 +310,9 @@ private:
     std::vector<CompactUnwindEntry> unwindInfos = createUnwindInfoEntries(
         mergedFile, unwindLocs, personalities, dwarfFrames);
 
+    // Remove any unused eh-frame atoms.
+    pruneUnusedEHFrames(mergedFile, unwindInfos, unwindLocs, dwarfFrames);
+
     // Finally, we can start creating pages based on these entries.
 
     DEBUG(llvm::dbgs() << "  Splitting entries into pages\n");
@@ -470,6 +473,54 @@ private:
     return unwindInfos;
   }
 
+  /// Remove unused EH frames.
+  ///
+  /// An EH frame is considered unused if there is a corresponding compact
+  /// unwind atom that doesn't require the EH frame.
+  void pruneUnusedEHFrames(
+                   SimpleFile &mergedFile,
+                   const std::vector<CompactUnwindEntry> &unwindInfos,
+                   const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
+                   const std::map<const Atom *, const Atom *> &dwarfFrames) {
+
+    // Worklist of all 'used' FDEs.
+    std::vector<const DefinedAtom *> usedDwarfWorklist;
+
+    // We have to check two conditions when building the worklist:
+    // (1) EH frames used by compact unwind entries.
+    for (auto &entry : unwindInfos)
+      if (entry.ehFrame)
+        usedDwarfWorklist.push_back(cast<DefinedAtom>(entry.ehFrame));
+
+    // (2) EH frames that reference functions with no corresponding compact
+    //     unwind info.
+    for (auto &entry : dwarfFrames)
+      if (!unwindLocs.count(entry.first))
+        usedDwarfWorklist.push_back(cast<DefinedAtom>(entry.second));
+
+    // Add all transitively referenced CFI atoms by processing the worklist.
+    std::set<const Atom *> usedDwarfFrames;
+    while (!usedDwarfWorklist.empty()) {
+      const DefinedAtom *cfiAtom = usedDwarfWorklist.back();
+      usedDwarfWorklist.pop_back();
+      usedDwarfFrames.insert(cfiAtom);
+      for (const auto *ref : *cfiAtom) {
+        const DefinedAtom *cfiTarget = dyn_cast<DefinedAtom>(ref->target());
+        if (cfiTarget->contentType() == DefinedAtom::typeCFI)
+          usedDwarfWorklist.push_back(cfiTarget);
+      }
+    }
+
+    // Finally, delete all unreferenced CFI atoms.
+    mergedFile.removeDefinedAtomsIf([&](const DefinedAtom *atom) {
+      if ((atom->contentType() == DefinedAtom::typeCFI) &&
+          !usedDwarfFrames.count(atom))
+        return true;
+      return false;
+    });
+  }
+
+
   CompactUnwindEntry finalizeUnwindInfoEntryForAtom(
       const DefinedAtom *function,
       const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,

Modified: lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml?rev=251095&r1=251094&r2=251095&view=diff
==============================================================================
--- lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml (original)
+++ lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml Fri Oct 23 00:39:16 2015
@@ -67,7 +67,8 @@ defined-atoms:
         target:          _needsDwarfButNoCompactUnwind
 
 # Generic x86_64 CIE:
-  - type:            unwind-cfi
+  - name:            LCIE
+    type:            unwind-cfi
     content:         [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
                        01, 78, 10, 01, 10, 0C, 07, 08, 90, 01, 00, 00 ]
 
@@ -80,6 +81,9 @@ defined-atoms:
       - kind:            unwindFDEToFunction
         offset:          8
         target:          _needsDwarfButNoCompactUnwind
+      - kind:            negDelta32
+        offset:          4
+        target:          LCIE
 
   - type:            unwind-cfi
     content:         [ 24, 00, 00, 00, 44, 00, 00, 00, C8, FE, FF, FF,
@@ -90,7 +94,22 @@ defined-atoms:
       - kind:            unwindFDEToFunction
         offset:          8
         target:          _needsDwarfSaysCompactUnwind
+      - kind:            negDelta32
+        offset:          4
+        target:          LCIE
 
+  - type:            unwind-cfi
+    content:         [ 24, 00, 00, 00, 6C, 00, 00, 00, C8, FE, FF, FF,
+                       FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00,
+                       00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
+                       00, 00, 00, 00 ]
+    references:
+      - kind:            unwindFDEToFunction
+        offset:          8
+        target:          _main
+      - kind:            negDelta32
+        offset:          4
+        target:          LCIE
 
   - name:            __Z3barv
     scope:           global

Modified: lld/trunk/test/mach-o/write-final-sections.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/write-final-sections.yaml?rev=251095&r1=251094&r2=251095&view=diff
==============================================================================
--- lld/trunk/test/mach-o/write-final-sections.yaml (original)
+++ lld/trunk/test/mach-o/write-final-sections.yaml Fri Oct 23 00:39:16 2015
@@ -69,12 +69,31 @@ defined-atoms:
 # CHECK-NEXT: )
 
 #  For __TEXT, __eh_frame, (with typeCFI)
+  - name:            LCIE
+    type:            unwind-cfi
+    content:         [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
+                       01, 78, 10, 01, 10, 0C, 07, 08, 90, 01, 00, 00 ]
+
   - type:            unwind-cfi
-    content:         [ 07 ]
+    content:         [ 24, 00, 00, 00, 1C, 00, 00, 00, C8, FE, FF, FF,
+                       FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00,
+                       00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
+                       00, 00, 00, 00 ]
+    references:
+      - kind:            unwindFDEToFunction
+        offset:          8
+        target:          _foo
+      - kind:            negDelta32
+        offset:          4
+        target:          LCIE
+
 # CHECK: Name: __eh_frame
 # CHECK: Segment: __TEXT
 # CHECK: SectionData (
-# CHECK-NEXT: 0000: 07
+# CHECK-NEXT:      0000: 14000000 00000000 017A5200 01781001
+# CHECK-NEXT:      0010: 100C0708 90010000 24000000 1C000000
+# CHECK-NEXT:      0020: 70FFFFFF FFFFFFFF 01000000 00000000
+# CHECK-NEXT:      0030: 00410E10 8602430D 06000000 00000000
 # CHECK-NEXT: )
 
 #  For __DATA, __data, (with typeData)




More information about the llvm-commits mailing list