[PATCH] Make dead-striping to handle reverse edges.
Rui Ueyama
ruiu at google.com
Mon Jun 2 01:00:32 PDT 2014
Hi Bigcheese, shankarke, atanasyan,
Layout-before edges are no longer used for layout, but they are
still there for dead-stripping. If we would just remove them
from code, LLD would wrongly remove live atoms that were
referenced by layout-befores.
This patch fixes the issue. Before dead-stripping, it scans all
atoms to construct a reverse map for layout-after edges. Dead-
stripping pass uses the map to traverse the graph.
http://reviews.llvm.org/D3986
Files:
include/lld/Core/Resolver.h
lib/Core/Resolver.cpp
test/core/dead-strip-reverse.objtxt
Index: include/lld/Core/Resolver.h
===================================================================
--- include/lld/Core/Resolver.h
+++ include/lld/Core/Resolver.h
@@ -14,6 +14,7 @@
#include "lld/Core/SharedLibraryFile.h"
#include "lld/Core/SymbolTable.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include <set>
@@ -105,6 +106,7 @@
std::set<const Atom *> _deadStripRoots;
llvm::DenseSet<const Atom *> _liveAtoms;
std::unique_ptr<MergedFile> _result;
+ llvm::DenseMap<const Atom *, llvm::DenseSet<const Atom *>> _reverseRef;
};
} // namespace lld
Index: lib/Core/Resolver.cpp
===================================================================
--- lib/Core/Resolver.cpp
+++ lib/Core/Resolver.cpp
@@ -312,19 +312,34 @@
return;
// Mark all atoms it references as live
- if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&atom))
+ if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&atom)) {
for (const Reference *ref : *defAtom)
if (const Atom *target = ref->target())
markLive(*target);
+ for (const Atom *target : _reverseRef[defAtom])
+ markLive(*target);
+ }
+}
+
+static bool isBackref(const Reference *ref) {
+ return ref->kindNamespace() == lld::Reference::KindNamespace::all &&
+ ref->kindValue() == lld::Reference::kindLayoutBefore;
}
// remove all atoms not actually used
void Resolver::deadStripOptimize() {
ScopedTask task(getDefaultDomain(), "deadStripOptimize");
// only do this optimization with -dead_strip
if (!_context.deadStrip())
return;
- assert(_liveAtoms.empty());
+
+ // Some type of references prevent referring atoms to be dead-striped.
+ // Make a reverse map of such references before traversing the graph.
+ for (const Atom *atom : _atoms)
+ if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom))
+ for (const Reference *ref : *defAtom)
+ if (isBackref(ref))
+ _reverseRef[ref->target()].insert(atom);
// By default, shared libraries are built with all globals as dead strip roots
if (_context.globalsAreDeadStripRoots())
Index: test/core/dead-strip-reverse.objtxt
===================================================================
--- /dev/null
+++ test/core/dead-strip-reverse.objtxt
@@ -0,0 +1,25 @@
+# RUN: lld -core --dead-strip %s | FileCheck -check-prefix=CHECK1 %s
+# RUN: lld -core %s | FileCheck -check-prefix=CHECK2 %s
+
+---
+defined-atoms:
+ - name: entry
+ dead-strip: never
+ scope: global
+ references:
+ - kind: layout-after
+ offset: 0
+ target: def
+ - name: def
+ scope: global
+ - name: dead
+ scope: global
+...
+
+# CHECK1: name: entry
+# CHECK1: name: def
+# CHECK1-NOT: name: dead
+
+# CHECK2: name: entry
+# CHECK2: name: def
+# CHECK2: name: dead
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3986.10007.patch
Type: text/x-patch
Size: 2927 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140602/1af953b0/attachment.bin>
More information about the llvm-commits
mailing list