Delete unused global aliases with internal linkage.
authorDuncan Sands <baldrick@free.fr>
Mon, 5 Jan 2009 20:37:33 +0000 (20:37 +0000)
committerDuncan Sands <baldrick@free.fr>
Mon, 5 Jan 2009 20:37:33 +0000 (20:37 +0000)
In fact this also deletes those with linkonce linkage,
however this is currently dead because for the moment
aliases aren't allowed to have this linkage type.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61742 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/GlobalDCE.cpp
test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll [new file with mode: 0644]

index 50bf85ba8ea14f663c233b1bfc919857cba91a8f..37ac94ae47efa36af8b11defec282bbab2b1ed7c 100644 (file)
@@ -25,6 +25,7 @@
 #include <set>
 using namespace llvm;
 
+STATISTIC(NumAliases, "Number of global aliases removed");
 STATISTIC(NumFunctions, "Number of functions removed");
 STATISTIC(NumVariables, "Number of global variables removed");
 
@@ -32,7 +33,7 @@ namespace {
   struct VISIBILITY_HIDDEN GlobalDCE : public ModulePass {
     static char ID; // Pass identification, replacement for typeid
     GlobalDCE() : ModulePass(&ID) {}
+
     // run - Do the GlobalDCE pass on the specified module, optionally updating
     // the specified callgraph to reflect the changes.
     //
@@ -41,7 +42,7 @@ namespace {
   private:
     std::set<GlobalValue*> AliveGlobals;
 
-    /// GlobalIsNeeded - the specific global value as needed, and
+    /// GlobalIsNeeded - mark the specific global value as needed, and
     /// recursively mark anything that it uses as also needed.
     void GlobalIsNeeded(GlobalValue *GV);
     void MarkUsedGlobalsAsNeeded(Constant *C);
@@ -77,11 +78,12 @@ bool GlobalDCE::runOnModule(Module &M) {
       GlobalIsNeeded(I);
   }
 
-
   for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
        I != E; ++I) {
-    // Aliases are always needed even if they are not used.
-    MarkUsedGlobalsAsNeeded(I->getAliasee());
+    Changed |= RemoveUnusedGlobalValue(*I);
+    // Externally visible aliases are needed.
+    if (!I->hasInternalLinkage() && !I->hasLinkOnceLinkage())
+      GlobalIsNeeded(I);
   }
 
   // Now that all globals which are needed are in the AliveGlobals set, we loop
@@ -96,7 +98,6 @@ bool GlobalDCE::runOnModule(Module &M) {
       I->setInitializer(0);
     }
 
-
   // The second pass drops the bodies of functions which are dead...
   std::vector<Function*> DeadFunctions;
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
@@ -107,7 +108,7 @@ bool GlobalDCE::runOnModule(Module &M) {
     }
 
   if (!DeadFunctions.empty()) {
-    // Now that all interreferences have been dropped, delete the actual objects
+    // Now that all interferences have been dropped, delete the actual objects
     // themselves.
     for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
       RemoveUnusedGlobalValue(*DeadFunctions[i]);
@@ -126,6 +127,17 @@ bool GlobalDCE::runOnModule(Module &M) {
     Changed = true;
   }
 
+  // Now delete any dead aliases.
+  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;) {
+    Module::alias_iterator J = I++;
+    if (!AliveGlobals.count(J)) {
+      RemoveUnusedGlobalValue(*J);
+      M.getAliasList().erase(J);
+      ++NumAliases;
+      Changed = true;
+    }
+  }
+
   // Make sure that all memory is released
   AliveGlobals.clear();
   return Changed;
@@ -147,7 +159,10 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
     // referenced by the initializer to the alive set.
     if (GV->hasInitializer())
       MarkUsedGlobalsAsNeeded(GV->getInitializer());
-  } else if (!isa<GlobalAlias>(G)) {
+  } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) {
+    // The target of a global alias is needed.
+    MarkUsedGlobalsAsNeeded(GA->getAliasee());
+  } else {
     // Otherwise this must be a function object.  We have to scan the body of
     // the function looking for constants and global values which are used as
     // operands.  Any operands of these types must be processed to ensure that
diff --git a/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll b/test/Transforms/GlobalDCE/2009-01-05-DeadAliases.ll
new file mode 100644 (file)
index 0000000..264b81d
--- /dev/null
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -globaldce | llvm-dis | not grep @D
+; RUN: llvm-as < %s | opt -globaldce | llvm-dis | grep @L | count 3
+
+@A = global i32 0
+@D = alias internal i32* @A
+@L1 = alias i32* @A
+@L2 = alias internal i32* @L1
+@L3 = alias i32* @L2