diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2014-10-07 07:07:19 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2014-10-07 07:07:19 +0000 |
| commit | e025321d36ab92dc36fd1071aa042ec6743cd617 (patch) | |
| tree | 23d648953d18aa2ded25b2afd139063c77fabc48 /llvm/lib | |
| parent | 7348322390b5185c69b3cf344dbeccd7cf3e56fb (diff) | |
| download | bcm5719-llvm-e025321d36ab92dc36fd1071aa042ec6743cd617.tar.gz bcm5719-llvm-e025321d36ab92dc36fd1071aa042ec6743cd617.zip | |
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.
llvm-svn: 219191
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/IPO/GlobalDCE.cpp | 39 |
1 files changed, 14 insertions, 25 deletions
diff --git a/llvm/lib/Transforms/IPO/GlobalDCE.cpp b/llvm/lib/Transforms/IPO/GlobalDCE.cpp index e50cdb7358c..f4d5536b37b 100644 --- a/llvm/lib/Transforms/IPO/GlobalDCE.cpp +++ b/llvm/lib/Transforms/IPO/GlobalDCE.cpp @@ -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(GlobalValue *G) { // 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. |

