LLVM 23.0.0git
LoopLoadElimination.cpp
Go to the documentation of this file.
1//===- LoopLoadElimination.cpp - Loop Load Elimination Pass ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implement a loop-aware load elimination pass.
10//
11// It uses LoopAccessAnalysis to identify loop-carried dependences with a
12// distance of one between stores and loads. These form the candidates for the
13// transformation. The source value of each store then propagated to the user
14// of the corresponding load. This makes the load dead.
15//
16// The pass can also version the loop and add memchecks in order to prove that
17// may-aliasing stores can't change the value in memory before it's read by the
18// load.
19//
20//===----------------------------------------------------------------------===//
21
23#include "llvm/ADT/APInt.h"
24#include "llvm/ADT/DenseMap.h"
26#include "llvm/ADT/STLExtras.h"
29#include "llvm/ADT/Statistic.h"
42#include "llvm/IR/DataLayout.h"
43#include "llvm/IR/Dominators.h"
45#include "llvm/IR/PassManager.h"
46#include "llvm/IR/Type.h"
47#include "llvm/IR/Value.h"
50#include "llvm/Support/Debug.h"
57#include <algorithm>
58#include <cassert>
59#include <forward_list>
60#include <tuple>
61#include <utility>
62
63using namespace llvm;
64
65#define LLE_OPTION "loop-load-elim"
66#define DEBUG_TYPE LLE_OPTION
67
69 "runtime-check-per-loop-load-elim", cl::Hidden,
70 cl::desc("Max number of memchecks allowed per eliminated load on average"),
71 cl::init(1));
72
74 "loop-load-elimination-scev-check-threshold", cl::init(8), cl::Hidden,
75 cl::desc("The maximum number of SCEV checks allowed for Loop "
76 "Load Elimination"));
77
78STATISTIC(NumLoopLoadEliminted, "Number of loads eliminated by LLE");
79
80namespace {
81
82/// Represent a store-to-forwarding candidate.
83struct StoreToLoadForwardingCandidate {
84 LoadInst *Load;
85 StoreInst *Store;
86
87 StoreToLoadForwardingCandidate(LoadInst *Load, StoreInst *Store)
88 : Load(Load), Store(Store) {}
89
90 /// Return true if the dependence from the store to the load has an
91 /// absolute distance of one.
92 /// E.g. A[i+1] = A[i] (or A[i-1] = A[i] for descending loop)
93 bool isDependenceDistanceOfOne(PredicatedScalarEvolution &PSE, Loop *L,
94 const DominatorTree &DT) const {
95 Value *LoadPtr = Load->getPointerOperand();
96 Value *StorePtr = Store->getPointerOperand();
97 Type *LoadType = getLoadStoreType(Load);
98 auto &DL = Load->getDataLayout();
99
100 assert(LoadPtr->getType()->getPointerAddressSpace() ==
101 StorePtr->getType()->getPointerAddressSpace() &&
102 DL.getTypeSizeInBits(LoadType) ==
103 DL.getTypeSizeInBits(getLoadStoreType(Store)) &&
104 "Should be a known dependence");
105
106 int64_t StrideLoad =
107 getPtrStride(PSE, LoadType, LoadPtr, L, DT).value_or(0);
108 int64_t StrideStore =
109 getPtrStride(PSE, LoadType, StorePtr, L, DT).value_or(0);
110 if (!StrideLoad || !StrideStore || StrideLoad != StrideStore)
111 return false;
112
113 // TODO: This check for stride values other than 1 and -1 can be eliminated.
114 // However, doing so may cause the LoopAccessAnalysis to overcompensate,
115 // generating numerous non-wrap runtime checks that may undermine the
116 // benefits of load elimination. To safely implement support for non-unit
117 // strides, we would need to ensure either that the processed case does not
118 // require these additional checks, or improve the LAA to handle them more
119 // efficiently, or potentially both.
120 if (std::abs(StrideLoad) != 1)
121 return false;
122
123 unsigned TypeByteSize = DL.getTypeAllocSize(LoadType);
124
125 auto *LoadPtrSCEV = cast<SCEVAddRecExpr>(PSE.getSCEV(LoadPtr));
126 auto *StorePtrSCEV = cast<SCEVAddRecExpr>(PSE.getSCEV(StorePtr));
127
128 // We don't need to check non-wrapping here because forward/backward
129 // dependence wouldn't be valid if these weren't monotonic accesses.
130 auto *Dist = dyn_cast<SCEVConstant>(
131 PSE.getSE()->getMinusSCEV(StorePtrSCEV, LoadPtrSCEV));
132 if (!Dist)
133 return false;
134 const APInt &Val = Dist->getAPInt();
135 return Val == TypeByteSize * StrideLoad;
136 }
137
138 Value *getLoadPtr() const { return Load->getPointerOperand(); }
139
140#ifndef NDEBUG
141 friend raw_ostream &operator<<(raw_ostream &OS,
142 const StoreToLoadForwardingCandidate &Cand) {
143 OS << *Cand.Store << " -->\n";
144 OS.indent(2) << *Cand.Load << "\n";
145 return OS;
146 }
147#endif
148};
149
150} // end anonymous namespace
151
152/// Check if the store dominates all latches, so as long as there is no
153/// intervening store this value will be loaded in the next iteration.
154static bool doesStoreDominatesAllLatches(BasicBlock *StoreBlock, Loop *L,
155 DominatorTree *DT) {
157 L->getLoopLatches(Latches);
158 return llvm::all_of(Latches, [&](const BasicBlock *Latch) {
159 return DT->dominates(StoreBlock, Latch);
160 });
161}
162
163/// Return true if the load is not executed on all paths in the loop.
164static bool isLoadConditional(LoadInst *Load, Loop *L) {
165 return Load->getParent() != L->getHeader();
166}
167
168namespace {
169
170/// The per-loop class that does most of the work.
171class LoadEliminationForLoop {
172public:
173 LoadEliminationForLoop(Loop *L, LoopInfo *LI, const LoopAccessInfo &LAI,
174 DominatorTree *DT, BlockFrequencyInfo *BFI,
175 ProfileSummaryInfo* PSI)
176 : L(L), LI(LI), LAI(LAI), DT(DT), BFI(BFI), PSI(PSI), PSE(LAI.getPSE()) {}
177
178 /// Look through the loop-carried and loop-independent dependences in
179 /// this loop and find store->load dependences.
180 ///
181 /// Note that no candidate is returned if LAA has failed to analyze the loop
182 /// (e.g. if it's not bottom-tested, contains volatile memops, etc.)
183 std::forward_list<StoreToLoadForwardingCandidate>
184 findStoreToLoadDependences(const LoopAccessInfo &LAI) {
185 std::forward_list<StoreToLoadForwardingCandidate> Candidates;
186
187 const auto &DepChecker = LAI.getDepChecker();
188 const auto *Deps = DepChecker.getDependences();
189 if (!Deps)
190 return Candidates;
191
192 // Find store->load dependences (consequently true dep). Both lexically
193 // forward and backward dependences qualify. Disqualify loads that have
194 // other unknown dependences.
195
196 SmallPtrSet<Instruction *, 4> LoadsWithUnknownDependence;
197
198 for (const auto &Dep : *Deps) {
199 Instruction *Source = Dep.getSource(DepChecker);
200 Instruction *Destination = Dep.getDestination(DepChecker);
201
205 if (isa<LoadInst>(Source))
206 LoadsWithUnknownDependence.insert(Source);
207 if (isa<LoadInst>(Destination))
208 LoadsWithUnknownDependence.insert(Destination);
209 continue;
210 }
211
212 if (Dep.isBackward())
213 // Note that the designations source and destination follow the program
214 // order, i.e. source is always first. (The direction is given by the
215 // DepType.)
216 std::swap(Source, Destination);
217 else
218 assert(Dep.isForward() && "Needs to be a forward dependence");
219
220 auto *Store = dyn_cast<StoreInst>(Source);
221 if (!Store)
222 continue;
223 auto *Load = dyn_cast<LoadInst>(Destination);
224 if (!Load)
225 continue;
226
227 // Only propagate if the stored values are bit/pointer castable.
230 Store->getDataLayout()))
231 continue;
232
233 Candidates.emplace_front(Load, Store);
234 }
235
236 if (!LoadsWithUnknownDependence.empty())
237 Candidates.remove_if([&](const StoreToLoadForwardingCandidate &C) {
238 return LoadsWithUnknownDependence.count(C.Load);
239 });
240
241 return Candidates;
242 }
243
244 /// Return the index of the instruction according to program order.
245 unsigned getInstrIndex(Instruction *Inst) {
246 auto I = InstOrder.find(Inst);
247 assert(I != InstOrder.end() && "No index for instruction");
248 return I->second;
249 }
250
251 /// If a load has multiple candidates associated (i.e. different
252 /// stores), it means that it could be forwarding from multiple stores
253 /// depending on control flow. Remove these candidates.
254 ///
255 /// Here, we rely on LAA to include the relevant loop-independent dependences.
256 /// LAA is known to omit these in the very simple case when the read and the
257 /// write within an alias set always takes place using the *same* pointer.
258 ///
259 /// However, we know that this is not the case here, i.e. we can rely on LAA
260 /// to provide us with loop-independent dependences for the cases we're
261 /// interested. Consider the case for example where a loop-independent
262 /// dependece S1->S2 invalidates the forwarding S3->S2.
263 ///
264 /// A[i] = ... (S1)
265 /// ... = A[i] (S2)
266 /// A[i+1] = ... (S3)
267 ///
268 /// LAA will perform dependence analysis here because there are two
269 /// *different* pointers involved in the same alias set (&A[i] and &A[i+1]).
270 void removeDependencesFromMultipleStores(
271 std::forward_list<StoreToLoadForwardingCandidate> &Candidates) {
272 // If Store is nullptr it means that we have multiple stores forwarding to
273 // this store.
274 using LoadToSingleCandT =
275 DenseMap<LoadInst *, const StoreToLoadForwardingCandidate *>;
276 LoadToSingleCandT LoadToSingleCand;
277
278 for (const auto &Cand : Candidates) {
279 bool NewElt;
280 LoadToSingleCandT::iterator Iter;
281
282 std::tie(Iter, NewElt) =
283 LoadToSingleCand.insert(std::make_pair(Cand.Load, &Cand));
284 if (!NewElt) {
285 const StoreToLoadForwardingCandidate *&OtherCand = Iter->second;
286 // Already multiple stores forward to this load.
287 if (OtherCand == nullptr)
288 continue;
289
290 // Handle the very basic case when the two stores are in the same block
291 // so deciding which one forwards is easy. The later one forwards as
292 // long as they both have a dependence distance of one to the load.
293 if (Cand.Store->getParent() == OtherCand->Store->getParent() &&
294 Cand.isDependenceDistanceOfOne(PSE, L, *DT) &&
295 OtherCand->isDependenceDistanceOfOne(PSE, L, *DT)) {
296 // They are in the same block, the later one will forward to the load.
297 if (getInstrIndex(OtherCand->Store) < getInstrIndex(Cand.Store))
298 OtherCand = &Cand;
299 } else
300 OtherCand = nullptr;
301 }
302 }
303
304 Candidates.remove_if([&](const StoreToLoadForwardingCandidate &Cand) {
305 if (LoadToSingleCand[Cand.Load] != &Cand) {
307 dbgs() << "Removing from candidates: \n"
308 << Cand
309 << " The load may have multiple stores forwarding to "
310 << "it\n");
311 return true;
312 }
313 return false;
314 });
315 }
316
317 /// Given two pointers operations by their RuntimePointerChecking
318 /// indices, return true if they require an alias check.
319 ///
320 /// We need a check if one is a pointer for a candidate load and the other is
321 /// a pointer for a possibly intervening store.
322 bool needsChecking(unsigned PtrIdx1, unsigned PtrIdx2,
323 const SmallPtrSetImpl<Value *> &PtrsWrittenOnFwdingPath,
324 const SmallPtrSetImpl<Value *> &CandLoadPtrs) {
325 Value *Ptr1 =
326 LAI.getRuntimePointerChecking()->getPointerInfo(PtrIdx1).PointerValue;
327 Value *Ptr2 =
328 LAI.getRuntimePointerChecking()->getPointerInfo(PtrIdx2).PointerValue;
329 return ((PtrsWrittenOnFwdingPath.count(Ptr1) && CandLoadPtrs.count(Ptr2)) ||
330 (PtrsWrittenOnFwdingPath.count(Ptr2) && CandLoadPtrs.count(Ptr1)));
331 }
332
333 /// Return pointers that are possibly written to on the path from a
334 /// forwarding store to a load.
335 ///
336 /// These pointers need to be alias-checked against the forwarding candidates.
337 SmallPtrSet<Value *, 4> findPointersWrittenOnForwardingPath(
338 const SmallVectorImpl<StoreToLoadForwardingCandidate> &Candidates) {
339 // From FirstStore to LastLoad neither of the elimination candidate loads
340 // should overlap with any of the stores.
341 //
342 // E.g.:
343 //
344 // st1 C[i]
345 // ld1 B[i] <-------,
346 // ld0 A[i] <----, | * LastLoad
347 // ... | |
348 // st2 E[i] | |
349 // st3 B[i+1] -- | -' * FirstStore
350 // st0 A[i+1] ---'
351 // st4 D[i]
352 //
353 // st0 forwards to ld0 if the accesses in st4 and st1 don't overlap with
354 // ld0.
355
356 LoadInst *LastLoad =
357 llvm::max_element(Candidates,
358 [&](const StoreToLoadForwardingCandidate &A,
359 const StoreToLoadForwardingCandidate &B) {
360 return getInstrIndex(A.Load) <
361 getInstrIndex(B.Load);
362 })
363 ->Load;
364 StoreInst *FirstStore =
365 llvm::min_element(Candidates,
366 [&](const StoreToLoadForwardingCandidate &A,
367 const StoreToLoadForwardingCandidate &B) {
368 return getInstrIndex(A.Store) <
369 getInstrIndex(B.Store);
370 })
371 ->Store;
372
373 // We're looking for stores after the first forwarding store until the end
374 // of the loop, then from the beginning of the loop until the last
375 // forwarded-to load. Collect the pointer for the stores.
376 SmallPtrSet<Value *, 4> PtrsWrittenOnFwdingPath;
377
378 auto InsertStorePtr = [&](Instruction *I) {
379 if (auto *S = dyn_cast<StoreInst>(I))
380 PtrsWrittenOnFwdingPath.insert(S->getPointerOperand());
381 };
382 const auto &MemInstrs = LAI.getDepChecker().getMemoryInstructions();
383 std::for_each(MemInstrs.begin() + getInstrIndex(FirstStore) + 1,
384 MemInstrs.end(), InsertStorePtr);
385 std::for_each(MemInstrs.begin(), &MemInstrs[getInstrIndex(LastLoad)],
386 InsertStorePtr);
387
388 return PtrsWrittenOnFwdingPath;
389 }
390
391 /// Determine the pointer alias checks to prove that there are no
392 /// intervening stores.
393 SmallVector<RuntimePointerCheck, 4> collectMemchecks(
394 const SmallVectorImpl<StoreToLoadForwardingCandidate> &Candidates) {
395
396 SmallPtrSet<Value *, 4> PtrsWrittenOnFwdingPath =
397 findPointersWrittenOnForwardingPath(Candidates);
398
399 // Collect the pointers of the candidate loads.
400 SmallPtrSet<Value *, 4> CandLoadPtrs;
401 for (const auto &Candidate : Candidates)
402 CandLoadPtrs.insert(Candidate.getLoadPtr());
403
404 const auto &AllChecks = LAI.getRuntimePointerChecking()->getChecks();
405 SmallVector<RuntimePointerCheck, 4> Checks;
406
407 copy_if(AllChecks, std::back_inserter(Checks),
408 [&](const RuntimePointerCheck &Check) {
409 for (auto PtrIdx1 : Check.first->Members)
410 for (auto PtrIdx2 : Check.second->Members)
411 if (needsChecking(PtrIdx1, PtrIdx2, PtrsWrittenOnFwdingPath,
412 CandLoadPtrs))
413 return true;
414 return false;
415 });
416
417 LLVM_DEBUG(dbgs() << "\nPointer Checks (count: " << Checks.size()
418 << "):\n");
419 LLVM_DEBUG(LAI.getRuntimePointerChecking()->printChecks(dbgs(), Checks));
420
421 return Checks;
422 }
423
424 /// Perform the transformation for a candidate.
425 void
426 propagateStoredValueToLoadUsers(const StoreToLoadForwardingCandidate &Cand,
427 SCEVExpander &SEE) {
428 // loop:
429 // %x = load %gep_i
430 // = ... %x
431 // store %y, %gep_i_plus_1
432 //
433 // =>
434 //
435 // ph:
436 // %x.initial = load %gep_0
437 // loop:
438 // %x.storeforward = phi [%x.initial, %ph] [%y, %loop]
439 // %x = load %gep_i <---- now dead
440 // = ... %x.storeforward
441 // store %y, %gep_i_plus_1
442
443 Value *Ptr = Cand.Load->getPointerOperand();
444 auto *PtrSCEV = cast<SCEVAddRecExpr>(PSE.getSCEV(Ptr));
445 auto *PH = L->getLoopPreheader();
446 assert(PH && "Preheader should exist!");
447 Value *InitialPtr = SEE.expandCodeFor(PtrSCEV->getStart(), Ptr->getType(),
448 PH->getTerminator());
450 new LoadInst(Cand.Load->getType(), InitialPtr, "load_initial",
451 /* isVolatile */ false, Cand.Load->getAlign(),
452 PH->getTerminator()->getIterator());
453 // We don't give any debug location to Initial, because it is inserted
454 // into the loop's preheader. A debug location inside the loop will cause
455 // a misleading stepping when debugging. The test update-debugloc-store
456 // -forwarded.ll checks this.
457 Initial->setDebugLoc(DebugLoc::getDropped());
458
459 PHINode *PHI = PHINode::Create(Initial->getType(), 2, "store_forwarded");
460 PHI->insertBefore(L->getHeader()->begin());
461 PHI->addIncoming(Initial, PH);
462
463 Type *LoadType = Initial->getType();
464 Type *StoreType = Cand.Store->getValueOperand()->getType();
465 auto &DL = Cand.Load->getDataLayout();
466 (void)DL;
467
468 assert(DL.getTypeSizeInBits(LoadType) == DL.getTypeSizeInBits(StoreType) &&
469 "The type sizes should match!");
470
471 Value *StoreValue = Cand.Store->getValueOperand();
472 if (LoadType != StoreType) {
473 StoreValue = CastInst::CreateBitOrPointerCast(StoreValue, LoadType,
474 "store_forward_cast",
475 Cand.Store->getIterator());
476 // Because it casts the old `load` value and is used by the new `phi`
477 // which replaces the old `load`, we give the `load`'s debug location
478 // to it.
479 cast<Instruction>(StoreValue)->setDebugLoc(Cand.Load->getDebugLoc());
480 }
481
482 PHI->addIncoming(StoreValue, L->getLoopLatch());
483
484 Cand.Load->replaceAllUsesWith(PHI);
485 PHI->setDebugLoc(Cand.Load->getDebugLoc());
486 }
487
488 /// Top-level driver for each loop: find store->load forwarding
489 /// candidates, add run-time checks and perform transformation.
490 bool processLoop() {
491 LLVM_DEBUG(dbgs() << "\nIn \"" << L->getHeader()->getParent()->getName()
492 << "\" checking " << *L << "\n");
493
494 // Look for store-to-load forwarding cases across the
495 // backedge. E.g.:
496 //
497 // loop:
498 // %x = load %gep_i
499 // = ... %x
500 // store %y, %gep_i_plus_1
501 //
502 // =>
503 //
504 // ph:
505 // %x.initial = load %gep_0
506 // loop:
507 // %x.storeforward = phi [%x.initial, %ph] [%y, %loop]
508 // %x = load %gep_i <---- now dead
509 // = ... %x.storeforward
510 // store %y, %gep_i_plus_1
511
512 // First start with store->load dependences.
513 auto StoreToLoadDependences = findStoreToLoadDependences(LAI);
514 if (StoreToLoadDependences.empty())
515 return false;
516
517 // Generate an index for each load and store according to the original
518 // program order. This will be used later.
519 InstOrder = LAI.getDepChecker().generateInstructionOrderMap();
520
521 // To keep things simple for now, remove those where the load is potentially
522 // fed by multiple stores.
523 removeDependencesFromMultipleStores(StoreToLoadDependences);
524 if (StoreToLoadDependences.empty())
525 return false;
526
527 // Filter the candidates further.
529 for (const StoreToLoadForwardingCandidate &Cand : StoreToLoadDependences) {
530 LLVM_DEBUG(dbgs() << "Candidate " << Cand);
531
532 // Make sure that the stored values is available everywhere in the loop in
533 // the next iteration.
534 if (!doesStoreDominatesAllLatches(Cand.Store->getParent(), L, DT))
535 continue;
536
537 // If the load is conditional we can't hoist its 0-iteration instance to
538 // the preheader because that would make it unconditional. Thus we would
539 // access a memory location that the original loop did not access.
540 if (isLoadConditional(Cand.Load, L))
541 continue;
542
543 // Check whether the SCEV difference is the same as the induction step,
544 // thus we load the value in the next iteration.
545 if (!Cand.isDependenceDistanceOfOne(PSE, L, *DT))
546 continue;
547
548 assert(isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Load->getPointerOperand())) &&
549 "Loading from something other than indvar?");
550 assert(
551 isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Store->getPointerOperand())) &&
552 "Storing to something other than indvar?");
553
554 Candidates.push_back(Cand);
556 dbgs()
557 << Candidates.size()
558 << ". Valid store-to-load forwarding across the loop backedge\n");
559 }
560 if (Candidates.empty())
561 return false;
562
563 // Check intervening may-alias stores. These need runtime checks for alias
564 // disambiguation.
565 SmallVector<RuntimePointerCheck, 4> Checks = collectMemchecks(Candidates);
566
567 // Too many checks are likely to outweigh the benefits of forwarding.
568 if (Checks.size() > Candidates.size() * CheckPerElim) {
569 LLVM_DEBUG(dbgs() << "Too many run-time checks needed.\n");
570 return false;
571 }
572
573 if (LAI.getPSE().getPredicate().getComplexity() >
575 LLVM_DEBUG(dbgs() << "Too many SCEV run-time checks needed.\n");
576 return false;
577 }
578
579 if (!L->isLoopSimplifyForm()) {
580 LLVM_DEBUG(dbgs() << "Loop is not is loop-simplify form");
581 return false;
582 }
583
584 if (!Checks.empty() || !LAI.getPSE().getPredicate().isAlwaysTrue()) {
585 if (LAI.hasConvergentOp()) {
586 LLVM_DEBUG(dbgs() << "Versioning is needed but not allowed with "
587 "convergent calls\n");
588 return false;
589 }
590
591 auto *HeaderBB = L->getHeader();
592 if (llvm::shouldOptimizeForSize(HeaderBB, PSI, BFI,
593 PGSOQueryType::IRPass)) {
595 dbgs() << "Versioning is needed but not allowed when optimizing "
596 "for size.\n");
597 return false;
598 }
599
600 // Point of no-return, start the transformation. First, version the loop
601 // if necessary.
602
603 // Forming LCSSA is a precondition of versioning.
604 if (!L->isRecursivelyLCSSAForm(*DT, *LI))
605 formLCSSARecursively(*L, *DT, LI, PSE.getSE());
606
607 LoopVersioning LV(LAI, Checks, L, LI, DT, PSE.getSE());
608 LV.versionLoop();
609
610 // After versioning, some of the candidates' pointers could stop being
611 // SCEVAddRecs. We need to filter them out.
612 auto NoLongerGoodCandidate = [this](
613 const StoreToLoadForwardingCandidate &Cand) {
614 return !isa<SCEVAddRecExpr>(
615 PSE.getSCEV(Cand.Load->getPointerOperand())) ||
617 PSE.getSCEV(Cand.Store->getPointerOperand()));
618 };
619 llvm::erase_if(Candidates, NoLongerGoodCandidate);
620 }
621
622 // Next, propagate the value stored by the store to the users of the load.
623 // Also for the first iteration, generate the initial value of the load.
624 SCEVExpander SEE(*PSE.getSE(), "storeforward");
625 for (const auto &Cand : Candidates)
626 propagateStoredValueToLoadUsers(Cand, SEE);
627 NumLoopLoadEliminted += Candidates.size();
628
629 return true;
630 }
631
632private:
633 Loop *L;
634
635 /// Maps the load/store instructions to their index according to
636 /// program order.
637 DenseMap<Instruction *, unsigned> InstOrder;
638
639 // Analyses used.
640 LoopInfo *LI;
641 const LoopAccessInfo &LAI;
642 DominatorTree *DT;
643 BlockFrequencyInfo *BFI;
644 ProfileSummaryInfo *PSI;
645 PredicatedScalarEvolution PSE;
646};
647
648} // end anonymous namespace
649
651 DominatorTree &DT,
655 LoopAccessInfoManager &LAIs) {
656 // Build up a worklist of inner-loops to transform to avoid iterator
657 // invalidation.
658 // FIXME: This logic comes from other passes that actually change the loop
659 // nest structure. It isn't clear this is necessary (or useful) for a pass
660 // which merely optimizes the use of loads in a loop.
661 SmallVector<Loop *, 8> Worklist;
662
663 bool Changed = false;
664
665 for (Loop *TopLevelLoop : LI)
666 for (Loop *L : depth_first(TopLevelLoop)) {
667 Changed |= simplifyLoop(L, &DT, &LI, SE, AC, /*MSSAU*/ nullptr, false);
668 // We only handle inner-most loops.
669 if (L->isInnermost())
670 Worklist.push_back(L);
671 }
672
673 // Now walk the identified inner loops.
674 for (Loop *L : Worklist) {
675 // Match historical behavior
676 if (!L->isRotatedForm() || !L->getExitingBlock())
677 continue;
678 // The actual work is performed by LoadEliminationForLoop.
679 LoadEliminationForLoop LEL(L, &LI, LAIs.getInfo(*L), &DT, BFI, PSI);
680 Changed |= LEL.processLoop();
681 if (Changed)
682 LAIs.clear();
683 }
684 return Changed;
685}
686
689 auto &LI = AM.getResult<LoopAnalysis>(F);
690 // There are no loops in the function. Return before computing other expensive
691 // analyses.
692 if (LI.empty())
693 return PreservedAnalyses::all();
694 auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
695 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
696 auto &AC = AM.getResult<AssumptionAnalysis>(F);
697 auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
698 auto *PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
699 auto *BFI = (PSI && PSI->hasProfileSummary()) ?
700 &AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
702
703 bool Changed = eliminateLoadsAcrossLoops(F, LI, DT, BFI, PSI, &SE, &AC, LAIs);
704
705 if (!Changed)
706 return PreservedAnalyses::all();
707
711 return PA;
712}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
#define Check(C,...)
This is the interface for a simple mod/ref and alias analysis over globals.
This header defines various interfaces for pass management in LLVM.
This header provides classes for managing per-loop analyses.
static bool eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI, DominatorTree &DT, BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, ScalarEvolution *SE, AssumptionCache *AC, LoopAccessInfoManager &LAIs)
static cl::opt< unsigned > LoadElimSCEVCheckThreshold("loop-load-elimination-scev-check-threshold", cl::init(8), cl::Hidden, cl::desc("The maximum number of SCEV checks allowed for Loop " "Load Elimination"))
static bool isLoadConditional(LoadInst *Load, Loop *L)
Return true if the load is not executed on all paths in the loop.
static bool doesStoreDominatesAllLatches(BasicBlock *StoreBlock, Loop *L, DominatorTree *DT)
Check if the store dominates all latches, so as long as there is no intervening store this value will...
static cl::opt< unsigned > CheckPerElim("runtime-check-per-loop-load-elim", cl::Hidden, cl::desc("Max number of memchecks allowed per eliminated load on average"), cl::init(1))
This header defines the LoopLoadEliminationPass object.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file contains some templates that are useful if you are working with the STL at all.
static bool processLoop(Loop &L, const AArch64Subtarget &ST, DataLayout DL)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
static LLVM_ABI bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op.
static LLVM_ABI CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
static DebugLoc getDropped()
Definition DebugLoc.h:155
Analysis pass which computes a DominatorTree.
Definition Dominators.h:270
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:151
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
An instruction for reading from memory.
Value * getPointerOperand()
Align getAlign() const
Return the alignment of the access that is being performed.
This analysis provides dependence information for the memory accesses of a loop.
LLVM_ABI const LoopAccessInfo & getInfo(Loop &L, bool AllowPartial=false)
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:587
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getSCEV(Value *V)
Returns the SCEV expression of V, in the context of the current SCEV predicate.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Value * getValueOperand()
Value * getPointerOperand()
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Changed
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)
Simplify each loop in a loop nest recursively.
auto min_element(R &&Range)
Provide wrappers to std::min_element which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2078
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
Definition LCSSA.cpp:449
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
std::pair< const RuntimeCheckingPtrGroup *, const RuntimeCheckingPtrGroup * > RuntimePointerCheck
A memcheck which made up of a pair of grouped pointers.
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1791
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2088
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2192
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI std::optional< int64_t > getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr, const Loop *Lp, const DominatorTree &DT, const DenseMap< Value *, const SCEV * > &StridesMap=DenseMap< Value *, const SCEV * >(), bool ShouldCheckWrap=true, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
If the pointer has a constant stride return it in units of the access type size.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
#define SEE(c)
Definition regcomp.c:248
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)