@@ -160,15 +160,15 @@ static bool isLeakCheckerRoot(GlobalVariable *GV) {
160
160
// / Given a value that is stored to a global but never read, determine whether
161
161
// / it's safe to remove the store and the chain of computation that feeds the
162
162
// / store.
163
- static bool IsSafeComputationToRemove (
163
+ static bool isSafeComputationToRemove (
164
164
Value *V, function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
165
+ assert (isa<Instruction>(V) && " Expected an instruction" );
165
166
do {
166
167
if (isa<Constant>(V))
167
168
return true ;
168
- if (! V->hasOneUse () )
169
+ if (V->getNumUses () > 0 )
169
170
return false ;
170
- if (isa<LoadInst>(V) || isa<InvokeInst>(V) || isa<Argument>(V) ||
171
- isa<GlobalValue>(V))
171
+ if (isa<LoadInst, InvokeInst, Argument, GlobalValue>(V))
172
172
return false ;
173
173
if (isAllocationFn (V, GetTLI))
174
174
return true ;
@@ -191,7 +191,7 @@ static bool IsSafeComputationToRemove(
191
191
// / any that obviously don't assign the global a value that isn't dynamically
192
192
// / allocated.
193
193
static bool
194
- CleanupPointerRootUsers (GlobalVariable *GV,
194
+ cleanupPointerRootUsers (GlobalVariable *GV,
195
195
function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
196
196
// A brief explanation of leak checkers. The goal is to find bugs where
197
197
// pointers are forgotten, causing an accumulating growth in memory
@@ -203,10 +203,7 @@ CleanupPointerRootUsers(GlobalVariable *GV,
203
203
// destroy it.
204
204
205
205
bool Changed = false ;
206
-
207
- // If Dead[n].first is the only use of a malloc result, we can delete its
208
- // chain of computation and the store to the global in Dead[n].second.
209
- SmallVector<std::pair<Instruction *, Instruction *>, 32 > Dead;
206
+ SmallVector<Instruction *> Dead;
210
207
211
208
SmallVector<User *> Worklist (GV->users ());
212
209
// Constants can't be pointers to dynamically allocated memory.
@@ -218,46 +215,44 @@ CleanupPointerRootUsers(GlobalVariable *GV,
218
215
Changed = true ;
219
216
SI->eraseFromParent ();
220
217
} else if (Instruction *I = dyn_cast<Instruction>(V)) {
221
- if (I-> hasOneUse ())
222
- Dead. push_back ( std::make_pair (I, SI) );
218
+ Dead. push_back (I);
219
+ SI-> eraseFromParent ( );
223
220
}
224
221
} else if (MemSetInst *MSI = dyn_cast<MemSetInst>(U)) {
225
222
if (isa<Constant>(MSI->getValue ())) {
226
223
Changed = true ;
227
224
MSI->eraseFromParent ();
228
225
} else if (Instruction *I = dyn_cast<Instruction>(MSI->getValue ())) {
229
- if (I-> hasOneUse ())
230
- Dead. push_back ( std::make_pair (I, MSI) );
226
+ Dead. push_back (I);
227
+ MSI-> eraseFromParent ( );
231
228
}
232
229
} else if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(U)) {
233
230
GlobalVariable *MemSrc = dyn_cast<GlobalVariable>(MTI->getSource ());
234
231
if (MemSrc && MemSrc->isConstant ()) {
235
232
Changed = true ;
236
233
MTI->eraseFromParent ();
237
234
} else if (Instruction *I = dyn_cast<Instruction>(MTI->getSource ())) {
238
- if (I-> hasOneUse ())
239
- Dead. push_back ( std::make_pair (I, MTI) );
235
+ Dead. push_back (I);
236
+ MTI-> eraseFromParent ( );
240
237
}
241
238
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
242
239
if (isa<GEPOperator>(CE))
243
240
append_range (Worklist, CE->users ());
244
241
}
245
242
}
246
243
247
- for (int i = 0 , e = Dead.size (); i != e; ++i) {
248
- if (IsSafeComputationToRemove (Dead[i].first , GetTLI)) {
249
- Dead[i].second ->eraseFromParent ();
250
- Instruction *I = Dead[i].first ;
244
+ for (auto *Inst : Dead) {
245
+ if (isSafeComputationToRemove (Inst, GetTLI)) {
251
246
do {
252
- if (isAllocationFn (I , GetTLI))
247
+ if (isAllocationFn (Inst , GetTLI))
253
248
break ;
254
- Instruction *J = dyn_cast<Instruction>(I ->getOperand (0 ));
249
+ Instruction *J = dyn_cast<Instruction>(Inst ->getOperand (0 ));
255
250
if (!J)
256
251
break ;
257
- I ->eraseFromParent ();
258
- I = J;
252
+ Inst ->eraseFromParent ();
253
+ Inst = J;
259
254
} while (true );
260
- I ->eraseFromParent ();
255
+ Inst ->eraseFromParent ();
261
256
Changed = true ;
262
257
}
263
258
}
@@ -269,8 +264,9 @@ CleanupPointerRootUsers(GlobalVariable *GV,
269
264
// / We just marked GV constant. Loop over all users of the global, cleaning up
270
265
// / the obvious ones. This is largely just a quick scan over the use list to
271
266
// / clean up the easy and obvious cruft. This returns true if it made a change.
272
- static bool CleanupConstantGlobalUsers (GlobalVariable *GV,
273
- const DataLayout &DL) {
267
+ static bool cleanupConstantGlobalUsers (
268
+ GlobalVariable *GV, const DataLayout &DL,
269
+ function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
274
270
Constant *Init = GV->getInitializer ();
275
271
SmallVector<User *, 8 > WorkList (GV->users ());
276
272
SmallPtrSet<User *, 8 > Visited;
@@ -872,10 +868,10 @@ static bool OptimizeAwayTrappingUsesOfLoads(
872
868
// nor is the global.
873
869
if (AllNonStoreUsesGone) {
874
870
if (isLeakCheckerRoot (GV)) {
875
- Changed |= CleanupPointerRootUsers (GV, GetTLI);
871
+ Changed |= cleanupPointerRootUsers (GV, GetTLI);
876
872
} else {
877
873
Changed = true ;
878
- CleanupConstantGlobalUsers (GV, DL);
874
+ cleanupConstantGlobalUsers (GV, DL, GetTLI );
879
875
}
880
876
if (GV->use_empty ()) {
881
877
LLVM_DEBUG (dbgs () << " *** GLOBAL NOW DEAD!\n " );
@@ -1494,11 +1490,11 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
1494
1490
1495
1491
if (isLeakCheckerRoot (GV)) {
1496
1492
// Delete any constant stores to the global.
1497
- Changed = CleanupPointerRootUsers (GV, GetTLI);
1493
+ Changed = cleanupPointerRootUsers (GV, GetTLI);
1498
1494
} else {
1499
1495
// Delete any stores we can find to the global. We may not be able to
1500
1496
// make it completely dead though.
1501
- Changed = CleanupConstantGlobalUsers (GV, DL);
1497
+ Changed = cleanupConstantGlobalUsers (GV, DL, GetTLI );
1502
1498
}
1503
1499
1504
1500
// If the global is dead now, delete it.
@@ -1523,7 +1519,7 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
1523
1519
}
1524
1520
1525
1521
// Clean up any obviously simplifiable users now.
1526
- Changed |= CleanupConstantGlobalUsers (GV, DL);
1522
+ Changed |= cleanupConstantGlobalUsers (GV, DL, GetTLI );
1527
1523
1528
1524
// If the global is dead now, just nuke it.
1529
1525
if (GV->use_empty ()) {
@@ -1578,7 +1574,7 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
1578
1574
}
1579
1575
1580
1576
// Clean up any obviously simplifiable users now.
1581
- CleanupConstantGlobalUsers (GV, DL);
1577
+ cleanupConstantGlobalUsers (GV, DL, GetTLI );
1582
1578
1583
1579
if (GV->use_empty ()) {
1584
1580
LLVM_DEBUG (dbgs () << " *** Substituting initializer allowed us to "
0 commit comments