mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-20 02:58:10 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219191 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ba2113f934
commit
2869d4800c
@ -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,26 +105,9 @@ 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
|
||||
// through the program, deleting those which are not alive.
|
||||
//
|
||||
@ -212,6 +188,19 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
|
||||
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.
|
||||
|
17
test/Transforms/GlobalDCE/pr20981.ll
Normal file
17
test/Transforms/GlobalDCE/pr20981.ll
Normal file
@ -0,0 +1,17 @@
|
||||
; RUN: opt < %s -globaldce -S | FileCheck %s
|
||||
|
||||
$c1 = comdat any
|
||||
; CHECK: $c1 = comdat any
|
||||
|
||||
@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
|
||||
}
|
Loading…
Reference in New Issue
Block a user