[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