]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===- SSAUpdater.cpp - Unstructured SSA Update Tool ----------------------===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file implements the SSAUpdater class. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
970d7e83 | 14 | #include "llvm/Transforms/Utils/SSAUpdater.h" |
223e47cc LB |
15 | #include "llvm/ADT/DenseMap.h" |
16 | #include "llvm/ADT/TinyPtrVector.h" | |
17 | #include "llvm/Analysis/InstructionSimplify.h" | |
1a4d82fc | 18 | #include "llvm/IR/CFG.h" |
970d7e83 LB |
19 | #include "llvm/IR/Constants.h" |
20 | #include "llvm/IR/Instructions.h" | |
21 | #include "llvm/IR/IntrinsicInst.h" | |
223e47cc LB |
22 | #include "llvm/Support/Debug.h" |
23 | #include "llvm/Support/raw_ostream.h" | |
24 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" | |
25 | #include "llvm/Transforms/Utils/Local.h" | |
223e47cc LB |
26 | #include "llvm/Transforms/Utils/SSAUpdaterImpl.h" |
27 | ||
28 | using namespace llvm; | |
29 | ||
1a4d82fc JJ |
30 | #define DEBUG_TYPE "ssaupdater" |
31 | ||
223e47cc LB |
32 | typedef DenseMap<BasicBlock*, Value*> AvailableValsTy; |
33 | static AvailableValsTy &getAvailableVals(void *AV) { | |
34 | return *static_cast<AvailableValsTy*>(AV); | |
35 | } | |
36 | ||
37 | SSAUpdater::SSAUpdater(SmallVectorImpl<PHINode*> *NewPHI) | |
1a4d82fc | 38 | : AV(nullptr), ProtoType(nullptr), ProtoName(), InsertedPHIs(NewPHI) {} |
223e47cc LB |
39 | |
40 | SSAUpdater::~SSAUpdater() { | |
41 | delete static_cast<AvailableValsTy*>(AV); | |
42 | } | |
43 | ||
223e47cc | 44 | void SSAUpdater::Initialize(Type *Ty, StringRef Name) { |
1a4d82fc | 45 | if (!AV) |
223e47cc LB |
46 | AV = new AvailableValsTy(); |
47 | else | |
48 | getAvailableVals(AV).clear(); | |
49 | ProtoType = Ty; | |
50 | ProtoName = Name; | |
51 | } | |
52 | ||
223e47cc LB |
53 | bool SSAUpdater::HasValueForBlock(BasicBlock *BB) const { |
54 | return getAvailableVals(AV).count(BB); | |
55 | } | |
56 | ||
223e47cc | 57 | void SSAUpdater::AddAvailableValue(BasicBlock *BB, Value *V) { |
1a4d82fc | 58 | assert(ProtoType && "Need to initialize SSAUpdater"); |
223e47cc LB |
59 | assert(ProtoType == V->getType() && |
60 | "All rewritten values must have the same type"); | |
61 | getAvailableVals(AV)[BB] = V; | |
62 | } | |
63 | ||
223e47cc | 64 | static bool IsEquivalentPHI(PHINode *PHI, |
1a4d82fc | 65 | SmallDenseMap<BasicBlock*, Value*, 8> &ValueMapping) { |
223e47cc LB |
66 | unsigned PHINumValues = PHI->getNumIncomingValues(); |
67 | if (PHINumValues != ValueMapping.size()) | |
68 | return false; | |
69 | ||
70 | // Scan the phi to see if it matches. | |
71 | for (unsigned i = 0, e = PHINumValues; i != e; ++i) | |
72 | if (ValueMapping[PHI->getIncomingBlock(i)] != | |
73 | PHI->getIncomingValue(i)) { | |
74 | return false; | |
75 | } | |
76 | ||
77 | return true; | |
78 | } | |
79 | ||
223e47cc LB |
80 | Value *SSAUpdater::GetValueAtEndOfBlock(BasicBlock *BB) { |
81 | Value *Res = GetValueAtEndOfBlockInternal(BB); | |
82 | return Res; | |
83 | } | |
84 | ||
223e47cc LB |
85 | Value *SSAUpdater::GetValueInMiddleOfBlock(BasicBlock *BB) { |
86 | // If there is no definition of the renamed variable in this block, just use | |
87 | // GetValueAtEndOfBlock to do our work. | |
88 | if (!HasValueForBlock(BB)) | |
89 | return GetValueAtEndOfBlock(BB); | |
90 | ||
91 | // Otherwise, we have the hard case. Get the live-in values for each | |
92 | // predecessor. | |
93 | SmallVector<std::pair<BasicBlock*, Value*>, 8> PredValues; | |
1a4d82fc | 94 | Value *SingularValue = nullptr; |
223e47cc LB |
95 | |
96 | // We can get our predecessor info by walking the pred_iterator list, but it | |
97 | // is relatively slow. If we already have PHI nodes in this block, walk one | |
98 | // of them to get the predecessor list instead. | |
99 | if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) { | |
100 | for (unsigned i = 0, e = SomePhi->getNumIncomingValues(); i != e; ++i) { | |
101 | BasicBlock *PredBB = SomePhi->getIncomingBlock(i); | |
102 | Value *PredVal = GetValueAtEndOfBlock(PredBB); | |
103 | PredValues.push_back(std::make_pair(PredBB, PredVal)); | |
104 | ||
105 | // Compute SingularValue. | |
106 | if (i == 0) | |
107 | SingularValue = PredVal; | |
108 | else if (PredVal != SingularValue) | |
1a4d82fc | 109 | SingularValue = nullptr; |
223e47cc LB |
110 | } |
111 | } else { | |
112 | bool isFirstPred = true; | |
113 | for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { | |
114 | BasicBlock *PredBB = *PI; | |
115 | Value *PredVal = GetValueAtEndOfBlock(PredBB); | |
116 | PredValues.push_back(std::make_pair(PredBB, PredVal)); | |
117 | ||
118 | // Compute SingularValue. | |
119 | if (isFirstPred) { | |
120 | SingularValue = PredVal; | |
121 | isFirstPred = false; | |
122 | } else if (PredVal != SingularValue) | |
1a4d82fc | 123 | SingularValue = nullptr; |
223e47cc LB |
124 | } |
125 | } | |
126 | ||
127 | // If there are no predecessors, just return undef. | |
128 | if (PredValues.empty()) | |
129 | return UndefValue::get(ProtoType); | |
130 | ||
131 | // Otherwise, if all the merged values are the same, just use it. | |
1a4d82fc | 132 | if (SingularValue) |
223e47cc LB |
133 | return SingularValue; |
134 | ||
135 | // Otherwise, we do need a PHI: check to see if we already have one available | |
136 | // in this block that produces the right value. | |
137 | if (isa<PHINode>(BB->begin())) { | |
1a4d82fc JJ |
138 | SmallDenseMap<BasicBlock*, Value*, 8> ValueMapping(PredValues.begin(), |
139 | PredValues.end()); | |
223e47cc LB |
140 | PHINode *SomePHI; |
141 | for (BasicBlock::iterator It = BB->begin(); | |
142 | (SomePHI = dyn_cast<PHINode>(It)); ++It) { | |
143 | if (IsEquivalentPHI(SomePHI, ValueMapping)) | |
144 | return SomePHI; | |
145 | } | |
146 | } | |
147 | ||
148 | // Ok, we have no way out, insert a new one now. | |
149 | PHINode *InsertedPHI = PHINode::Create(ProtoType, PredValues.size(), | |
150 | ProtoName, &BB->front()); | |
151 | ||
152 | // Fill in all the predecessors of the PHI. | |
153 | for (unsigned i = 0, e = PredValues.size(); i != e; ++i) | |
154 | InsertedPHI->addIncoming(PredValues[i].second, PredValues[i].first); | |
155 | ||
156 | // See if the PHI node can be merged to a single value. This can happen in | |
157 | // loop cases when we get a PHI of itself and one other value. | |
158 | if (Value *V = SimplifyInstruction(InsertedPHI)) { | |
159 | InsertedPHI->eraseFromParent(); | |
160 | return V; | |
161 | } | |
162 | ||
163 | // Set the DebugLoc of the inserted PHI, if available. | |
164 | DebugLoc DL; | |
165 | if (const Instruction *I = BB->getFirstNonPHI()) | |
166 | DL = I->getDebugLoc(); | |
167 | InsertedPHI->setDebugLoc(DL); | |
168 | ||
169 | // If the client wants to know about all new instructions, tell it. | |
170 | if (InsertedPHIs) InsertedPHIs->push_back(InsertedPHI); | |
171 | ||
172 | DEBUG(dbgs() << " Inserted PHI: " << *InsertedPHI << "\n"); | |
173 | return InsertedPHI; | |
174 | } | |
175 | ||
223e47cc LB |
176 | void SSAUpdater::RewriteUse(Use &U) { |
177 | Instruction *User = cast<Instruction>(U.getUser()); | |
178 | ||
179 | Value *V; | |
180 | if (PHINode *UserPN = dyn_cast<PHINode>(User)) | |
181 | V = GetValueAtEndOfBlock(UserPN->getIncomingBlock(U)); | |
182 | else | |
183 | V = GetValueInMiddleOfBlock(User->getParent()); | |
184 | ||
185 | // Notify that users of the existing value that it is being replaced. | |
186 | Value *OldVal = U.get(); | |
187 | if (OldVal != V && OldVal->hasValueHandle()) | |
188 | ValueHandleBase::ValueIsRAUWd(OldVal, V); | |
189 | ||
190 | U.set(V); | |
191 | } | |
192 | ||
223e47cc LB |
193 | void SSAUpdater::RewriteUseAfterInsertions(Use &U) { |
194 | Instruction *User = cast<Instruction>(U.getUser()); | |
195 | ||
196 | Value *V; | |
197 | if (PHINode *UserPN = dyn_cast<PHINode>(User)) | |
198 | V = GetValueAtEndOfBlock(UserPN->getIncomingBlock(U)); | |
199 | else | |
200 | V = GetValueAtEndOfBlock(User->getParent()); | |
201 | ||
202 | U.set(V); | |
203 | } | |
204 | ||
223e47cc LB |
205 | namespace llvm { |
206 | template<> | |
207 | class SSAUpdaterTraits<SSAUpdater> { | |
208 | public: | |
209 | typedef BasicBlock BlkT; | |
210 | typedef Value *ValT; | |
211 | typedef PHINode PhiT; | |
212 | ||
213 | typedef succ_iterator BlkSucc_iterator; | |
214 | static BlkSucc_iterator BlkSucc_begin(BlkT *BB) { return succ_begin(BB); } | |
215 | static BlkSucc_iterator BlkSucc_end(BlkT *BB) { return succ_end(BB); } | |
216 | ||
217 | class PHI_iterator { | |
218 | private: | |
219 | PHINode *PHI; | |
220 | unsigned idx; | |
221 | ||
222 | public: | |
223 | explicit PHI_iterator(PHINode *P) // begin iterator | |
224 | : PHI(P), idx(0) {} | |
225 | PHI_iterator(PHINode *P, bool) // end iterator | |
226 | : PHI(P), idx(PHI->getNumIncomingValues()) {} | |
227 | ||
228 | PHI_iterator &operator++() { ++idx; return *this; } | |
229 | bool operator==(const PHI_iterator& x) const { return idx == x.idx; } | |
230 | bool operator!=(const PHI_iterator& x) const { return !operator==(x); } | |
231 | Value *getIncomingValue() { return PHI->getIncomingValue(idx); } | |
232 | BasicBlock *getIncomingBlock() { return PHI->getIncomingBlock(idx); } | |
233 | }; | |
234 | ||
235 | static PHI_iterator PHI_begin(PhiT *PHI) { return PHI_iterator(PHI); } | |
236 | static PHI_iterator PHI_end(PhiT *PHI) { | |
237 | return PHI_iterator(PHI, true); | |
238 | } | |
239 | ||
240 | /// FindPredecessorBlocks - Put the predecessors of Info->BB into the Preds | |
241 | /// vector, set Info->NumPreds, and allocate space in Info->Preds. | |
242 | static void FindPredecessorBlocks(BasicBlock *BB, | |
243 | SmallVectorImpl<BasicBlock*> *Preds) { | |
244 | // We can get our predecessor info by walking the pred_iterator list, | |
245 | // but it is relatively slow. If we already have PHI nodes in this | |
246 | // block, walk one of them to get the predecessor list instead. | |
247 | if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) { | |
248 | for (unsigned PI = 0, E = SomePhi->getNumIncomingValues(); PI != E; ++PI) | |
249 | Preds->push_back(SomePhi->getIncomingBlock(PI)); | |
250 | } else { | |
251 | for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) | |
252 | Preds->push_back(*PI); | |
253 | } | |
254 | } | |
255 | ||
256 | /// GetUndefVal - Get an undefined value of the same type as the value | |
257 | /// being handled. | |
258 | static Value *GetUndefVal(BasicBlock *BB, SSAUpdater *Updater) { | |
259 | return UndefValue::get(Updater->ProtoType); | |
260 | } | |
261 | ||
262 | /// CreateEmptyPHI - Create a new PHI instruction in the specified block. | |
263 | /// Reserve space for the operands but do not fill them in yet. | |
264 | static Value *CreateEmptyPHI(BasicBlock *BB, unsigned NumPreds, | |
265 | SSAUpdater *Updater) { | |
266 | PHINode *PHI = PHINode::Create(Updater->ProtoType, NumPreds, | |
267 | Updater->ProtoName, &BB->front()); | |
268 | return PHI; | |
269 | } | |
270 | ||
271 | /// AddPHIOperand - Add the specified value as an operand of the PHI for | |
272 | /// the specified predecessor block. | |
273 | static void AddPHIOperand(PHINode *PHI, Value *Val, BasicBlock *Pred) { | |
274 | PHI->addIncoming(Val, Pred); | |
275 | } | |
276 | ||
277 | /// InstrIsPHI - Check if an instruction is a PHI. | |
278 | /// | |
279 | static PHINode *InstrIsPHI(Instruction *I) { | |
280 | return dyn_cast<PHINode>(I); | |
281 | } | |
282 | ||
283 | /// ValueIsPHI - Check if a value is a PHI. | |
284 | /// | |
285 | static PHINode *ValueIsPHI(Value *Val, SSAUpdater *Updater) { | |
286 | return dyn_cast<PHINode>(Val); | |
287 | } | |
288 | ||
289 | /// ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source | |
290 | /// operands, i.e., it was just added. | |
291 | static PHINode *ValueIsNewPHI(Value *Val, SSAUpdater *Updater) { | |
292 | PHINode *PHI = ValueIsPHI(Val, Updater); | |
293 | if (PHI && PHI->getNumIncomingValues() == 0) | |
294 | return PHI; | |
1a4d82fc | 295 | return nullptr; |
223e47cc LB |
296 | } |
297 | ||
298 | /// GetPHIValue - For the specified PHI instruction, return the value | |
299 | /// that it defines. | |
300 | static Value *GetPHIValue(PHINode *PHI) { | |
301 | return PHI; | |
302 | } | |
303 | }; | |
304 | ||
305 | } // End llvm namespace | |
306 | ||
1a4d82fc JJ |
307 | /// Check to see if AvailableVals has an entry for the specified BB and if so, |
308 | /// return it. If not, construct SSA form by first calculating the required | |
309 | /// placement of PHIs and then inserting new PHIs where needed. | |
223e47cc LB |
310 | Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) { |
311 | AvailableValsTy &AvailableVals = getAvailableVals(AV); | |
312 | if (Value *V = AvailableVals[BB]) | |
313 | return V; | |
314 | ||
315 | SSAUpdaterImpl<SSAUpdater> Impl(this, &AvailableVals, InsertedPHIs); | |
316 | return Impl.GetValue(BB); | |
317 | } | |
318 | ||
319 | //===----------------------------------------------------------------------===// | |
320 | // LoadAndStorePromoter Implementation | |
321 | //===----------------------------------------------------------------------===// | |
322 | ||
323 | LoadAndStorePromoter:: | |
324 | LoadAndStorePromoter(const SmallVectorImpl<Instruction*> &Insts, | |
325 | SSAUpdater &S, StringRef BaseName) : SSA(S) { | |
326 | if (Insts.empty()) return; | |
327 | ||
328 | Value *SomeVal; | |
329 | if (LoadInst *LI = dyn_cast<LoadInst>(Insts[0])) | |
330 | SomeVal = LI; | |
331 | else | |
332 | SomeVal = cast<StoreInst>(Insts[0])->getOperand(0); | |
333 | ||
334 | if (BaseName.empty()) | |
335 | BaseName = SomeVal->getName(); | |
336 | SSA.Initialize(SomeVal->getType(), BaseName); | |
337 | } | |
338 | ||
339 | ||
340 | void LoadAndStorePromoter:: | |
341 | run(const SmallVectorImpl<Instruction*> &Insts) const { | |
342 | ||
343 | // First step: bucket up uses of the alloca by the block they occur in. | |
344 | // This is important because we have to handle multiple defs/uses in a block | |
345 | // ourselves: SSAUpdater is purely for cross-block references. | |
346 | DenseMap<BasicBlock*, TinyPtrVector<Instruction*> > UsesByBlock; | |
347 | ||
348 | for (unsigned i = 0, e = Insts.size(); i != e; ++i) { | |
349 | Instruction *User = Insts[i]; | |
350 | UsesByBlock[User->getParent()].push_back(User); | |
351 | } | |
352 | ||
353 | // Okay, now we can iterate over all the blocks in the function with uses, | |
354 | // processing them. Keep track of which loads are loading a live-in value. | |
355 | // Walk the uses in the use-list order to be determinstic. | |
356 | SmallVector<LoadInst*, 32> LiveInLoads; | |
357 | DenseMap<Value*, Value*> ReplacedLoads; | |
358 | ||
359 | for (unsigned i = 0, e = Insts.size(); i != e; ++i) { | |
360 | Instruction *User = Insts[i]; | |
361 | BasicBlock *BB = User->getParent(); | |
362 | TinyPtrVector<Instruction*> &BlockUses = UsesByBlock[BB]; | |
363 | ||
364 | // If this block has already been processed, ignore this repeat use. | |
365 | if (BlockUses.empty()) continue; | |
366 | ||
367 | // Okay, this is the first use in the block. If this block just has a | |
368 | // single user in it, we can rewrite it trivially. | |
369 | if (BlockUses.size() == 1) { | |
370 | // If it is a store, it is a trivial def of the value in the block. | |
371 | if (StoreInst *SI = dyn_cast<StoreInst>(User)) { | |
372 | updateDebugInfo(SI); | |
373 | SSA.AddAvailableValue(BB, SI->getOperand(0)); | |
374 | } else | |
375 | // Otherwise it is a load, queue it to rewrite as a live-in load. | |
376 | LiveInLoads.push_back(cast<LoadInst>(User)); | |
377 | BlockUses.clear(); | |
378 | continue; | |
379 | } | |
380 | ||
381 | // Otherwise, check to see if this block is all loads. | |
382 | bool HasStore = false; | |
383 | for (unsigned i = 0, e = BlockUses.size(); i != e; ++i) { | |
384 | if (isa<StoreInst>(BlockUses[i])) { | |
385 | HasStore = true; | |
386 | break; | |
387 | } | |
388 | } | |
389 | ||
390 | // If so, we can queue them all as live in loads. We don't have an | |
391 | // efficient way to tell which on is first in the block and don't want to | |
392 | // scan large blocks, so just add all loads as live ins. | |
393 | if (!HasStore) { | |
394 | for (unsigned i = 0, e = BlockUses.size(); i != e; ++i) | |
395 | LiveInLoads.push_back(cast<LoadInst>(BlockUses[i])); | |
396 | BlockUses.clear(); | |
397 | continue; | |
398 | } | |
399 | ||
400 | // Otherwise, we have mixed loads and stores (or just a bunch of stores). | |
401 | // Since SSAUpdater is purely for cross-block values, we need to determine | |
402 | // the order of these instructions in the block. If the first use in the | |
403 | // block is a load, then it uses the live in value. The last store defines | |
404 | // the live out value. We handle this by doing a linear scan of the block. | |
1a4d82fc | 405 | Value *StoredValue = nullptr; |
223e47cc LB |
406 | for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { |
407 | if (LoadInst *L = dyn_cast<LoadInst>(II)) { | |
408 | // If this is a load from an unrelated pointer, ignore it. | |
409 | if (!isInstInList(L, Insts)) continue; | |
410 | ||
411 | // If we haven't seen a store yet, this is a live in use, otherwise | |
412 | // use the stored value. | |
413 | if (StoredValue) { | |
414 | replaceLoadWithValue(L, StoredValue); | |
415 | L->replaceAllUsesWith(StoredValue); | |
416 | ReplacedLoads[L] = StoredValue; | |
417 | } else { | |
418 | LiveInLoads.push_back(L); | |
419 | } | |
420 | continue; | |
421 | } | |
422 | ||
423 | if (StoreInst *SI = dyn_cast<StoreInst>(II)) { | |
424 | // If this is a store to an unrelated pointer, ignore it. | |
425 | if (!isInstInList(SI, Insts)) continue; | |
426 | updateDebugInfo(SI); | |
427 | ||
428 | // Remember that this is the active value in the block. | |
429 | StoredValue = SI->getOperand(0); | |
430 | } | |
431 | } | |
432 | ||
433 | // The last stored value that happened is the live-out for the block. | |
434 | assert(StoredValue && "Already checked that there is a store in block"); | |
435 | SSA.AddAvailableValue(BB, StoredValue); | |
436 | BlockUses.clear(); | |
437 | } | |
438 | ||
439 | // Okay, now we rewrite all loads that use live-in values in the loop, | |
440 | // inserting PHI nodes as necessary. | |
441 | for (unsigned i = 0, e = LiveInLoads.size(); i != e; ++i) { | |
442 | LoadInst *ALoad = LiveInLoads[i]; | |
443 | Value *NewVal = SSA.GetValueInMiddleOfBlock(ALoad->getParent()); | |
444 | replaceLoadWithValue(ALoad, NewVal); | |
445 | ||
446 | // Avoid assertions in unreachable code. | |
447 | if (NewVal == ALoad) NewVal = UndefValue::get(NewVal->getType()); | |
448 | ALoad->replaceAllUsesWith(NewVal); | |
449 | ReplacedLoads[ALoad] = NewVal; | |
450 | } | |
451 | ||
452 | // Allow the client to do stuff before we start nuking things. | |
453 | doExtraRewritesBeforeFinalDeletion(); | |
454 | ||
455 | // Now that everything is rewritten, delete the old instructions from the | |
456 | // function. They should all be dead now. | |
457 | for (unsigned i = 0, e = Insts.size(); i != e; ++i) { | |
458 | Instruction *User = Insts[i]; | |
459 | ||
460 | // If this is a load that still has uses, then the load must have been added | |
461 | // as a live value in the SSAUpdate data structure for a block (e.g. because | |
462 | // the loaded value was stored later). In this case, we need to recursively | |
463 | // propagate the updates until we get to the real value. | |
464 | if (!User->use_empty()) { | |
465 | Value *NewVal = ReplacedLoads[User]; | |
466 | assert(NewVal && "not a replaced load?"); | |
467 | ||
468 | // Propagate down to the ultimate replacee. The intermediately loads | |
469 | // could theoretically already have been deleted, so we don't want to | |
470 | // dereference the Value*'s. | |
471 | DenseMap<Value*, Value*>::iterator RLI = ReplacedLoads.find(NewVal); | |
472 | while (RLI != ReplacedLoads.end()) { | |
473 | NewVal = RLI->second; | |
474 | RLI = ReplacedLoads.find(NewVal); | |
475 | } | |
476 | ||
477 | replaceLoadWithValue(cast<LoadInst>(User), NewVal); | |
478 | User->replaceAllUsesWith(NewVal); | |
479 | } | |
480 | ||
481 | instructionDeleted(User); | |
482 | User->eraseFromParent(); | |
483 | } | |
484 | } | |
485 | ||
486 | bool | |
487 | LoadAndStorePromoter::isInstInList(Instruction *I, | |
488 | const SmallVectorImpl<Instruction*> &Insts) | |
489 | const { | |
490 | return std::find(Insts.begin(), Insts.end(), I) != Insts.end(); | |
491 | } |