aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-11-26 18:42:17 +0000
committerChris Lattner <sabre@nondot.org>2001-11-26 18:42:17 +0000
commit30474bb92912b5097d8a515fae1ce1f53676c2b2 (patch)
tree1aa373c534ff66a6e3ac03c95fe01397be216b4f /lib/Transforms
parent0bbe58f073b4b4a6f68b3e2ee6074fc314e8d19f (diff)
downloadexternal_llvm-30474bb92912b5097d8a515fae1ce1f53676c2b2.zip
external_llvm-30474bb92912b5097d8a515fae1ce1f53676c2b2.tar.gz
external_llvm-30474bb92912b5097d8a515fae1ce1f53676c2b2.tar.bz2
Implement DCE of global values
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1360 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/GlobalDCE.cpp59
-rw-r--r--lib/Transforms/IPO/Makefile6
2 files changed, 65 insertions, 0 deletions
diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp
new file mode 100644
index 0000000..24945c0
--- /dev/null
+++ b/lib/Transforms/IPO/GlobalDCE.cpp
@@ -0,0 +1,59 @@
+//===-- GlobalDCE.cpp - DCE unreachable internal methods ---------*- C++ -*--=//
+//
+// This transform is designed to eliminate unreachable internal globals
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO/GlobalDCE.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Support/DepthFirstIterator.h"
+#include "llvm/Module.h"
+#include "llvm/Method.h"
+#include <set>
+
+static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph *CG) {
+ // Create a call graph if one is not already available...
+ cfg::CallGraph &CallGraph = CG ? *CG : *new cfg::CallGraph(M);
+
+ // Calculate which methods are reachable from the external methods in the call
+ // graph.
+ //
+ set<cfg::CallGraphNode*> ReachableNodes(df_begin(&CallGraph),
+ df_end(&CallGraph));
+
+ // Loop over the methods in the module twice. The first time is used to drop
+ // references that methods have to each other before they are deleted. The
+ // second pass removes the methods that need to be removed.
+ //
+ vector<cfg::CallGraphNode*> MethodsToDelete; // Track unused methods
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
+ cfg::CallGraphNode *N = CallGraph[*I];
+ if (!ReachableNodes.count(N)) { // Not reachable??
+ (*I)->dropAllReferences();
+ N->removeAllCalledMethods();
+ MethodsToDelete.push_back(N);
+ }
+ }
+
+ // Nothing to do if no unreachable methods have been found...
+ if (MethodsToDelete.empty()) {
+ // Free the created call graph if it was not passed in
+ if (&CallGraph != CG) delete &CallGraph;
+ return false;
+ }
+
+ // Unreachables methods have been found and should have no references to them,
+ // delete them now.
+ //
+ for (vector<cfg::CallGraphNode*>::iterator I = MethodsToDelete.begin(),
+ E = MethodsToDelete.end(); I != E; ++I)
+ delete CallGraph.removeMethodFromModule(*I);
+
+ // Free the created call graph if it was not passed in
+ if (&CallGraph != CG) delete &CallGraph;
+ return true;
+}
+
+bool GlobalDCE::run(Module *M, cfg::CallGraph *CG = 0) {
+ return RemoveUnreachableMethods(M, CG);
+}
diff --git a/lib/Transforms/IPO/Makefile b/lib/Transforms/IPO/Makefile
new file mode 100644
index 0000000..778d2eb
--- /dev/null
+++ b/lib/Transforms/IPO/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../..
+
+LIBRARYNAME = ipo
+
+include $(LEVEL)/Makefile.common
+