llvm.org GIT mirror llvm / ff69509
Remove dangling initializers in GlobalDCE GlobalDCE deletes global vars and updates their initializers to nullptr while leaving underlying constants to be cleaned up later by its uses. The clean up may never happen, fix this by forcing it every time it's safe to destroy constants. Final patch by Rafael Espindola http://reviews.llvm.org/D4931 <rdar://problem/17523868> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216390 91177308-0d34-0410-b5e6-96231b3b80d8 Bruno Cardoso Lopes 5 years ago
3 changed file(s) with 26 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
2121 #include "llvm/IR/Instructions.h"
2222 #include "llvm/IR/Module.h"
2323 #include "llvm/Transforms/Utils/CtorUtils.h"
24 #include "llvm/Transforms/Utils/GlobalStatus.h"
2425 #include "llvm/Pass.h"
2526 using namespace llvm;
2627
140141 I != E; ++I)
141142 if (!AliveGlobals.count(I)) {
142143 DeadGlobalVars.push_back(I); // Keep track of dead globals
143 I->setInitializer(nullptr);
144 if (I->hasInitializer()) {
145 Constant *Init = I->getInitializer();
146 I->setInitializer(nullptr);
147 if (isSafeToDestroyConstant(Init))
148 Init->destroyConstant();
149 }
144150 }
145151
146152 // The second pass drops the bodies of functions which are dead...
3232 ///
3333 bool llvm::isSafeToDestroyConstant(const Constant *C) {
3434 if (isa(C))
35 return false;
36
37 if (isa(C) || isa(C))
3538 return false;
3639
3740 for (const User *U : C->users())
0 ; RUN: opt -globaldce -simplifycfg -S < %s | FileCheck %s
1
2 ; Tests whether globaldce does the right cleanup while removing @bar
3 ; so that a dead BlockAddress reference to foo won't prevent other passes
4 ; to work properly, e.g. simplifycfg
5 @bar = internal unnamed_addr constant i8* blockaddress(@foo, %L1)
6
7 ; CHECK-LABEL: foo
8 ; CHECK-NOT: br label %L1
9 ; CHECK: ret void
10 define void @foo() {
11 entry:
12 br label %L1
13 L1:
14 ret void
15 }