@@ -201,61 +201,54 @@ CleanupPointerRootUsers(GlobalVariable *GV,
201
201
202
202
bool Changed = false ;
203
203
204
- // If Dead[n].first is the only use of a malloc result, we can delete its
205
- // chain of computation and the store to the global in Dead[n].second.
206
- SmallVector<std::pair<Instruction *, Instruction *>, 32 > Dead;
207
-
204
+ // Collect all stores to GV.
205
+ SmallVector<Instruction *, 8 > Writes;
208
206
SmallVector<User *> Worklist (GV->users ());
209
- // Constants can't be pointers to dynamically allocated memory.
210
207
while (!Worklist.empty ()) {
211
208
User *U = Worklist.pop_back_val ();
212
- if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
213
- Value *V = SI->getValueOperand ();
214
- if (isa<Constant>(V)) {
215
- Changed = true ;
216
- SI->eraseFromParent ();
217
- } else if (Instruction *I = dyn_cast<Instruction>(V)) {
218
- if (I->hasOneUse ())
219
- Dead.push_back (std::make_pair (I, SI));
220
- }
221
- } else if (MemSetInst *MSI = dyn_cast<MemSetInst>(U)) {
222
- if (isa<Constant>(MSI->getValue ())) {
223
- Changed = true ;
224
- MSI->eraseFromParent ();
225
- } else if (Instruction *I = dyn_cast<Instruction>(MSI->getValue ())) {
226
- if (I->hasOneUse ())
227
- Dead.push_back (std::make_pair (I, MSI));
228
- }
229
- } else if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(U)) {
230
- GlobalVariable *MemSrc = dyn_cast<GlobalVariable>(MTI->getSource ());
231
- if (MemSrc && MemSrc->isConstant ()) {
232
- Changed = true ;
233
- MTI->eraseFromParent ();
234
- } else if (Instruction *I = dyn_cast<Instruction>(MTI->getSource ())) {
235
- if (I->hasOneUse ())
236
- Dead.push_back (std::make_pair (I, MTI));
237
- }
238
- } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
209
+ if (auto *SI = dyn_cast<StoreInst>(U)) {
210
+ Writes.push_back (SI);
211
+ } else if (auto *CE = dyn_cast<ConstantExpr>(U)) {
239
212
if (isa<GEPOperator>(CE))
240
213
append_range (Worklist, CE->users ());
214
+ } else if (auto *MI = dyn_cast<MemIntrinsic>(U)) {
215
+ if (MI->getRawDest () == GV)
216
+ Writes.push_back (MI);
241
217
}
242
218
}
243
219
244
- for (int i = 0 , e = Dead.size (); i != e; ++i) {
245
- if (IsSafeComputationToRemove (Dead[i].first , GetTLI)) {
246
- Dead[i].second ->eraseFromParent ();
247
- Instruction *I = Dead[i].first ;
248
- do {
249
- if (isAllocationFn (I, GetTLI))
250
- break ;
251
- Instruction *J = dyn_cast<Instruction>(I->getOperand (0 ));
252
- if (!J)
253
- break ;
254
- I->eraseFromParent ();
255
- I = J;
256
- } while (true );
220
+ auto RemoveComputationChain = [&GetTLI](Instruction *I) {
221
+ do {
222
+ if (isAllocationFn (I, GetTLI))
223
+ break ;
224
+ Instruction *J = dyn_cast<Instruction>(I->getOperand (0 ));
225
+ if (!J)
226
+ break ;
257
227
I->eraseFromParent ();
228
+ I = J;
229
+ } while (true );
230
+ I->eraseFromParent ();
231
+ };
232
+
233
+ // Remove the store if it's value operand is a constant or a computation
234
+ // chain. If the value operand is a computation chain, determine if it is safe
235
+ // to remove it before removing the store. Remove both the store and the
236
+ // computation chain if it is safe to do so.
237
+ while (!Writes.empty ()) {
238
+ auto *Write = Writes.pop_back_val ();
239
+ auto *V = Write->getOperand (0 );
240
+ if (isa<Constant>(V)) {
258
241
Changed = true ;
242
+ Write->eraseFromParent ();
243
+ } else if (isa<Instruction>(V)) {
244
+ if (IsSafeComputationToRemove (V, GetTLI)) {
245
+ Changed = true ;
246
+ Write->eraseFromParent ();
247
+ RemoveComputationChain (cast<Instruction>(V));
248
+ } else {
249
+ Changed = true ;
250
+ Write->eraseFromParent ();
251
+ }
259
252
}
260
253
}
261
254
0 commit comments