@@ -201,61 +201,54 @@ CleanupPointerRootUsers(GlobalVariable *GV,
201201
202202 bool Changed = false ;
203203
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;
208206 SmallVector<User *> Worklist (GV->users ());
209- // Constants can't be pointers to dynamically allocated memory.
210207 while (!Worklist.empty ()) {
211208 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)) {
239212 if (isa<GEPOperator>(CE))
240213 append_range (Worklist, CE->users ());
214+ } else if (auto *MI = dyn_cast<MemIntrinsic>(U)) {
215+ if (MI->getRawDest () == GV)
216+ Writes.push_back (MI);
241217 }
242218 }
243219
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 ;
257227 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)) {
258241 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+ }
259252 }
260253 }
261254
0 commit comments