[llvm] r219191 - GlobalDCE: Don't drop any COMDAT members

David Majnemer david.majnemer at gmail.com
Tue Oct 7 00:07:19 PDT 2014


Author: majnemer
Date: Tue Oct  7 02:07:19 2014
New Revision: 219191

URL: http://llvm.org/viewvc/llvm-project?rev=219191&view=rev
Log:
GlobalDCE: Don't drop any COMDAT members

If we require a single member of a comdat, require all of the other
members as well.

This fixes PR20981.

Added:
    llvm/trunk/test/Transforms/GlobalDCE/pr20981.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp

Modified: llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp?rev=219191&r1=219190&r2=219191&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalDCE.cpp Tue Oct  7 02:07:19 2014
@@ -78,9 +78,6 @@ bool GlobalDCE::runOnModule(Module &M) {
   // Remove empty functions from the global ctors list.
   Changed |= optimizeGlobalCtorsList(M, isEmptyFunction);
 
-  typedef std::multimap<const Comdat *, GlobalValue *> ComdatGVPairsTy;
-  ComdatGVPairsTy ComdatGVPairs;
-
   // Loop over the module, adding globals which are obviously necessary.
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
     Changed |= RemoveUnusedGlobalValue(*I);
@@ -88,8 +85,6 @@ bool GlobalDCE::runOnModule(Module &M) {
     if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) {
       if (!I->isDiscardableIfUnused())
         GlobalIsNeeded(I);
-      else if (const Comdat *C = I->getComdat())
-        ComdatGVPairs.insert(std::make_pair(C, I));
     }
   }
 
@@ -101,8 +96,6 @@ bool GlobalDCE::runOnModule(Module &M) {
     if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) {
       if (!I->isDiscardableIfUnused())
         GlobalIsNeeded(I);
-      else if (const Comdat *C = I->getComdat())
-        ComdatGVPairs.insert(std::make_pair(C, I));
     }
   }
 
@@ -112,24 +105,7 @@ bool GlobalDCE::runOnModule(Module &M) {
     // Externally visible aliases are needed.
     if (!I->isDiscardableIfUnused()) {
       GlobalIsNeeded(I);
-    } else if (const Comdat *C = I->getComdat()) {
-      ComdatGVPairs.insert(std::make_pair(C, I));
-    }
-  }
-
-  for (ComdatGVPairsTy::iterator I = ComdatGVPairs.begin(),
-                                 E = ComdatGVPairs.end();
-       I != E;) {
-    ComdatGVPairsTy::iterator UB = ComdatGVPairs.upper_bound(I->first);
-    bool CanDiscard = std::all_of(I, UB, [](ComdatGVPairsTy::value_type Pair) {
-      return Pair.second->isDiscardableIfUnused();
-    });
-    if (!CanDiscard) {
-      std::for_each(I, UB, [this](ComdatGVPairsTy::value_type Pair) {
-        GlobalIsNeeded(Pair.second);
-      });
     }
-    I = UB;
   }
 
   // Now that all globals which are needed are in the AliveGlobals set, we loop
@@ -211,7 +187,20 @@ void GlobalDCE::GlobalIsNeeded(GlobalVal
   // If the global is already in the set, no need to reprocess it.
   if (!AliveGlobals.insert(G))
     return;
-  
+
+  Module *M = G->getParent();
+  if (Comdat *C = G->getComdat()) {
+    for (Function &F : *M)
+      if (F.getComdat() == C)
+        GlobalIsNeeded(&F);
+    for (GlobalVariable &GV : M->globals())
+      if (GV.getComdat() == C)
+        GlobalIsNeeded(&GV);
+    for (GlobalAlias &GA : M->aliases())
+      if (GA.getComdat() == C)
+        GlobalIsNeeded(&GA);
+  }
+
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G)) {
     // If this is a global variable, we must make sure to add any global values
     // referenced by the initializer to the alive set.

Added: llvm/trunk/test/Transforms/GlobalDCE/pr20981.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalDCE/pr20981.ll?rev=219191&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GlobalDCE/pr20981.ll (added)
+++ llvm/trunk/test/Transforms/GlobalDCE/pr20981.ll Tue Oct  7 02:07:19 2014
@@ -0,0 +1,17 @@
+; RUN: opt < %s -globaldce -S | FileCheck %s
+
+$c1 = comdat any
+; CHECK: $c1 = comdat any
+
+ at a1 = linkonce_odr alias void ()* @f1
+; CHECK: @a1 = linkonce_odr alias void ()* @f1
+
+define linkonce_odr void @f1() comdat $c1 {
+  ret void
+}
+; CHECK: define linkonce_odr void @f1() comdat $c1
+
+define void @g() {
+  call void @f1()
+  ret void
+}





More information about the llvm-commits mailing list