LLVM 24.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 {
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.
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.
194 // Disqualify loads that have other unsafe dependences.
195
196 SmallPtrSet<Instruction *, 4> LoadsWithUnsafeDependence;
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 LoadsWithUnsafeDependence.insert(Source);
207 if (isa<LoadInst>(Destination))
208 LoadsWithUnsafeDependence.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 // This store may partially clobber the value from another forwarding
232 // candidate.
233 LoadsWithUnsafeDependence.insert(Load);
234 continue;
235 }
236
237 Candidates.emplace_front(Load, Store);
238 }
239
240 if (!LoadsWithUnsafeDependence.empty())
241 Candidates.remove_if([&](const StoreToLoadForwardingCandidate &C) {
242 return LoadsWithUnsafeDependence.count(C.Load);
243 });
244
245 return Candidates;
246 }
247
248 /// Return the index of the instruction according to program order.
249 unsigned getInstrIndex(Instruction *Inst) {
250 auto I = InstOrder.find(Inst);
251 assert(I != InstOrder.end() && "No index for instruction");
252 return I->second;
253 }
254
255 /// If a load has multiple candidates associated (i.e. different
256 /// stores), it means that it could be forwarding from multiple stores
257 /// depending on control flow. Remove these candidates.
258 ///
259 /// Here, we rely on LAA to include the relevant loop-independent dependences.
260 /// LAA is known to omit these in the very simple case when the read and the
261 /// write within an alias set always takes place using the *same* pointer.
262 ///
263 /// However, we know that this is not the case here, i.e. we can rely on LAA
264 /// to provide us with loop-independent dependences for the cases we're
265 /// interested. Consider the case for example where a loop-independent
266 /// dependece S1->S2 invalidates the forwarding S3->S2.
267 ///
268 /// A[i] = ... (S1)
269 /// ... = A[i] (S2)
270 /// A[i+1] = ... (S3)
271 ///
272 /// LAA will perform dependence analysis here because there are two
273 /// *different* pointers involved in the same alias set (&A[i] and &A[i+1]).
274 void removeDependencesFromMultipleStores(
275 std::forward_list<StoreToLoadForwardingCandidate> &Candidates) {
276 // If Store is nullptr it means that we have multiple stores forwarding to
277 // this store.
278 using LoadToSingleCandT =
279 DenseMap<LoadInst *, const StoreToLoadForwardingCandidate *>;
280 LoadToSingleCandT LoadToSingleCand;
281
282 for (const auto &Cand : Candidates) {
283 bool NewElt;
284 LoadToSingleCandT::iterator Iter;
285
286 std::tie(Iter, NewElt) =
287 LoadToSingleCand.insert(std::make_pair(Cand.Load, &Cand));
288 if (!NewElt) {
289 const StoreToLoadForwardingCandidate *&OtherCand = Iter->second;
290 // Already multiple stores forward to this load.
291 if (OtherCand == nullptr)
292 continue;
293
294 // Handle the very basic case when the two stores are in the same block
295 // so deciding which one forwards is easy. The later one forwards as
296 // long as they both have a dependence distance of one to the load.
297 if (Cand.Store->getParent() == OtherCand->Store->getParent() &&
298 Cand.isDependenceDistanceOfOne(PSE, L, *DT) &&
299 OtherCand->isDependenceDistanceOfOne(PSE, L, *DT)) {
300 // They are in the same block, the later one will forward to the load.
301 if (getInstrIndex(OtherCand->Store) < getInstrIndex(Cand.Store))
302 OtherCand = &Cand;
303 } else
304 OtherCand = nullptr;
305 }
306 }
307
308 Candidates.remove_if([&](const StoreToLoadForwardingCandidate &Cand) {
309 if (LoadToSingleCand[Cand.Load] != &Cand) {
311 dbgs() << "Removing from candidates: \n"
312 << Cand
313 << " The load may have multiple stores forwarding to "
314 << "it\n");
315 return true;
316 }
317 return false;
318 });
319 }
320
321 /// Given two pointers operations by their RuntimePointerChecking
322 /// indices, return true if they require an alias check.
323 ///
324 /// We need a check if one is a pointer for a candidate load and the other is
325 /// a pointer for a possibly intervening store.
326 bool needsChecking(unsigned PtrIdx1, unsigned PtrIdx2,
327 const SmallPtrSetImpl<Value *> &PtrsWrittenOnFwdingPath,
328 const SmallPtrSetImpl<Value *> &CandLoadPtrs) {
329 Value *Ptr1 =
330 LAI.getRuntimePointerChecking()->getPointerInfo(PtrIdx1).PointerValue;
331 Value *Ptr2 =
332 LAI.getRuntimePointerChecking()->getPointerInfo(PtrIdx2).PointerValue;
333 return ((PtrsWrittenOnFwdingPath.count(Ptr1) && CandLoadPtrs.count(Ptr2)) ||
334 (PtrsWrittenOnFwdingPath.count(Ptr2) && CandLoadPtrs.count(Ptr1)));
335 }
336
337 /// Return pointers that are possibly written to on the path from a
338 /// forwarding store to a load.
339 ///
340 /// These pointers need to be alias-checked against the forwarding candidates.
341 SmallPtrSet<Value *, 4> findPointersWrittenOnForwardingPath(
342 const SmallVectorImpl<StoreToLoadForwardingCandidate> &Candidates) {
343 // From FirstStore to LastLoad neither of the elimination candidate loads
344 // should overlap with any of the stores.
345 //
346 // E.g.:
347 //
348 // st1 C[i]
349 // ld1 B[i] <-------,
350 // ld0 A[i] <----, | * LastLoad
351 // ... | |
352 // st2 E[i] | |
353 // st3 B[i+1] -- | -' * FirstStore
354 // st0 A[i+1] ---'
355 // st4 D[i]
356 //
357 // st0 forwards to ld0 if the accesses in st4 and st1 don't overlap with
358 // ld0.
359
360 LoadInst *LastLoad =
361 llvm::max_element(Candidates,
362 [&](const StoreToLoadForwardingCandidate &A,
363 const StoreToLoadForwardingCandidate &B) {
364 return getInstrIndex(A.Load) <
365 getInstrIndex(B.Load);
366 })
367 ->Load;
368 StoreInst *FirstStore =
369 llvm::min_element(Candidates,
370 [&](const StoreToLoadForwardingCandidate &A,
371 const StoreToLoadForwardingCandidate &B) {
372 return getInstrIndex(A.Store) <
373 getInstrIndex(B.Store);
374 })
375 ->Store;
376
377 // We're looking for stores after the first forwarding store until the end
378 // of the loop, then from the beginning of the loop until the last
379 // forwarded-to load. Collect the pointer for the stores.
380 SmallPtrSet<Value *, 4> PtrsWrittenOnFwdingPath;
381
382 auto InsertStorePtr = [&](Instruction *I) {
383 if (auto *S = dyn_cast<StoreInst>(I))
384 PtrsWrittenOnFwdingPath.insert(S->getPointerOperand());
385 };
386 const auto &MemInstrs = LAI.getDepChecker().getMemoryInstructions();
387 std::for_each(MemInstrs.begin() + getInstrIndex(FirstStore) + 1,
388 MemInstrs.end(), InsertStorePtr);
389 std::for_each(MemInstrs.begin(), &MemInstrs[getInstrIndex(LastLoad)],
390 InsertStorePtr);
391
392 return PtrsWrittenOnFwdingPath;
393 }
394
395 /// Determine the pointer alias checks to prove that there are no
396 /// intervening stores.
397 SmallVector<RuntimePointerCheck, 4> collectMemchecks(
398 const SmallVectorImpl<StoreToLoadForwardingCandidate> &Candidates) {
399
400 SmallPtrSet<Value *, 4> PtrsWrittenOnFwdingPath =
401 findPointersWrittenOnForwardingPath(Candidates);
402
403 // Collect the pointers of the candidate loads.
404 SmallPtrSet<Value *, 4> CandLoadPtrs;
405 for (const auto &Candidate : Candidates)
406 CandLoadPtrs.insert(Candidate.getLoadPtr());
407
408 const auto &AllChecks = LAI.getRuntimePointerChecking()->getChecks();
409 SmallVector<RuntimePointerCheck, 4> Checks;
410
411 copy_if(AllChecks, std::back_inserter(Checks),
412 [&](const RuntimePointerCheck &Check) {
413 for (auto PtrIdx1 : Check.first->Members)
414 for (auto PtrIdx2 : Check.second->Members)
415 if (needsChecking(PtrIdx1, PtrIdx2, PtrsWrittenOnFwdingPath,
416 CandLoadPtrs))
417 return true;
418 return false;
419 });
420
421 LLVM_DEBUG(dbgs() << "\nPointer Checks (count: " << Checks.size()
422 << "):\n");
423 LLVM_DEBUG(LAI.getRuntimePointerChecking()->printChecks(dbgs(), Checks));
424
425 return Checks;
426 }
427
428 /// Perform the transformation for a candidate.
429 void
430 propagateStoredValueToLoadUsers(const StoreToLoadForwardingCandidate &Cand,
431 SCEVExpander &SEE) {
432 // loop:
433 // %x = load %gep_i
434 // = ... %x
435 // store %y, %gep_i_plus_1
436 //
437 // =>
438 //
439 // ph:
440 // %x.initial = load %gep_0
441 // loop:
442 // %x.storeforward = phi [%x.initial, %ph] [%y, %loop]
443 // %x = load %gep_i <---- now dead
444 // = ... %x.storeforward
445 // store %y, %gep_i_plus_1
446
447 Value *Ptr = Cand.Load->getPointerOperand();
448 auto *PtrSCEV = cast<SCEVAddRecExpr>(PSE.getSCEV(Ptr));
449 auto *PH = L->getLoopPreheader();
450 assert(PH && "Preheader should exist!");
451 Value *InitialPtr = SEE.expandCodeFor(PtrSCEV->getStart(), Ptr->getType(),
452 PH->getTerminator());
454 new LoadInst(Cand.Load->getType(), InitialPtr, "load_initial",
455 /* isVolatile */ false, Cand.Load->getAlign(),
456 PH->getTerminator()->getIterator());
457 // We don't give any debug location to Initial, because it is inserted
458 // into the loop's preheader. A debug location inside the loop will cause
459 // a misleading stepping when debugging. The test update-debugloc-store
460 // -forwarded.ll checks this.
461 Initial->setDebugLoc(DebugLoc::getDropped());
462
463 PHINode *PHI = PHINode::Create(Initial->getType(), 2, "store_forwarded");
464 PHI->insertBefore(L->getHeader()->begin());
465 PHI->addIncoming(Initial, PH);
466
467 Type *LoadType = Initial->getType();
468 Type *StoreType = Cand.Store->getValueOperand()->getType();
469 auto &DL = Cand.Load->getDataLayout();
470 (void)DL;
471
472 assert(DL.getTypeSizeInBits(LoadType) == DL.getTypeSizeInBits(StoreType) &&
473 "The type sizes should match!");
474
475 Value *StoreValue = Cand.Store->getValueOperand();
476 if (LoadType != StoreType) {
477 StoreValue = CastInst::CreateBitOrPointerCast(StoreValue, LoadType,
478 "store_forward_cast",
479 Cand.Store->getIterator());
480 // Because it casts the old `load` value and is used by the new `phi`
481 // which replaces the old `load`, we give the `load`'s debug location
482 // to it.
483 cast<Instruction>(StoreValue)->setDebugLoc(Cand.Load->getDebugLoc());
484 }
485
486 PHI->addIncoming(StoreValue, L->getLoopLatch());
487
488 Cand.Load->replaceAllUsesWith(PHI);
489 PHI->setDebugLoc(Cand.Load->getDebugLoc());
490 }
491
492 /// Top-level driver for each loop: find store->load forwarding
493 /// candidates, add run-time checks and perform transformation.
494 bool processLoop() {
495 LLVM_DEBUG(dbgs() << "\nIn \"" << L->getHeader()->getParent()->getName()
496 << "\" checking " << *L << "\n");
497
498 // Look for store-to-load forwarding cases across the
499 // backedge. E.g.:
500 //
501 // loop:
502 // %x = load %gep_i
503 // = ... %x
504 // store %y, %gep_i_plus_1
505 //
506 // =>
507 //
508 // ph:
509 // %x.initial = load %gep_0
510 // loop:
511 // %x.storeforward = phi [%x.initial, %ph] [%y, %loop]
512 // %x = load %gep_i <---- now dead
513 // = ... %x.storeforward
514 // store %y, %gep_i_plus_1
515
516 // First start with store->load dependences.
517 auto StoreToLoadDependences = findStoreToLoadDependences(LAI);
518 if (StoreToLoadDependences.empty())
519 return false;
520
521 // Generate an index for each load and store according to the original
522 // program order. This will be used later.
523 InstOrder = LAI.getDepChecker().generateInstructionOrderMap();
524
525 // To keep things simple for now, remove those where the load is potentially
526 // fed by multiple stores.
527 removeDependencesFromMultipleStores(StoreToLoadDependences);
528 if (StoreToLoadDependences.empty())
529 return false;
530
531 // Filter the candidates further.
533 for (const StoreToLoadForwardingCandidate &Cand : StoreToLoadDependences) {
534 LLVM_DEBUG(dbgs() << "Candidate " << Cand);
535
536 // Make sure that the stored values is available everywhere in the loop in
537 // the next iteration.
538 if (!doesStoreDominatesAllLatches(Cand.Store->getParent(), L, DT))
539 continue;
540
541 // If the load is conditional we can't hoist its 0-iteration instance to
542 // the preheader because that would make it unconditional. Thus we would
543 // access a memory location that the original loop did not access.
544 if (isLoadConditional(Cand.Load, L))
545 continue;
546
547 // Check whether the SCEV difference is the same as the induction step,
548 // thus we load the value in the next iteration.
549 if (!Cand.isDependenceDistanceOfOne(PSE, L, *DT))
550 continue;
551
552 assert(isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Load->getPointerOperand())) &&
553 "Loading from something other than indvar?");
554 assert(
555 isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Store->getPointerOperand())) &&
556 "Storing to something other than indvar?");
557
558 Candidates.push_back(Cand);
560 dbgs()
561 << Candidates.size()
562 << ". Valid store-to-load forwarding across the loop backedge\n");
563 }
564 if (Candidates.empty())
565 return false;
566
567 // Check intervening may-alias stores. These need runtime checks for alias
568 // disambiguation.
569 SmallVector<RuntimePointerCheck, 4> Checks = collectMemchecks(Candidates);
570
571 // Too many checks are likely to outweigh the benefits of forwarding.
572 if (Checks.size() > Candidates.size() * CheckPerElim) {
573 LLVM_DEBUG(dbgs() << "Too many run-time checks needed.\n");
574 return false;
575 }
576
577 if (LAI.getPSE().getPredicate().getComplexity() >
579 LLVM_DEBUG(dbgs() << "Too many SCEV run-time checks needed.\n");
580 return false;
581 }
582
583 if (!L->isLoopSimplifyForm()) {
584 LLVM_DEBUG(dbgs() << "Loop is not is loop-simplify form");
585 return false;
586 }
587
588 if (!Checks.empty() || !LAI.getPSE().getPredicate().isAlwaysTrue()) {
589 if (LAI.hasConvergentOp()) {
590 LLVM_DEBUG(dbgs() << "Versioning is needed but not allowed with "
591 "convergent calls\n");
592 return false;
593 }
594
595 auto *HeaderBB = L->getHeader();
596 if (llvm::shouldOptimizeForSize(HeaderBB, PSI, BFI,
597 PGSOQueryType::IRPass)) {
599 dbgs() << "Versioning is needed but not allowed when optimizing "
600 "for size.\n");
601 return false;
602 }
603
604 // Point of no-return, start the transformation. First, version the loop
605 // if necessary.
606
607 // Forming LCSSA is a precondition of versioning.
608 if (!L->isRecursivelyLCSSAForm(*DT, *LI))
609 formLCSSARecursively(*L, *DT, LI, PSE.getSE());
610
611 LoopVersioning LV(LAI, Checks, L, LI, DT, PSE.getSE());
612 LV.versionLoop();
613
614 // After versioning, some of the candidates' pointers could stop being
615 // SCEVAddRecs. We need to filter them out.
616 auto NoLongerGoodCandidate = [this](
617 const StoreToLoadForwardingCandidate &Cand) {
618 return !isa<SCEVAddRecExpr>(
619 PSE.getSCEV(Cand.Load->getPointerOperand())) ||
621 PSE.getSCEV(Cand.Store->getPointerOperand()));
622 };
623 llvm::erase_if(Candidates, NoLongerGoodCandidate);
624 }
625
626 // Next, propagate the value stored by the store to the users of the load.
627 // Also for the first iteration, generate the initial value of the load.
628 SCEVExpander SEE(*PSE.getSE(), "storeforward");
629 for (const auto &Cand : Candidates)
630 propagateStoredValueToLoadUsers(Cand, SEE);
631 NumLoopLoadEliminted += Candidates.size();
632
633 return true;
634 }
635
636private:
637 Loop *L;
638
639 /// Maps the load/store instructions to their index according to
640 /// program order.
641 DenseMap<Instruction *, unsigned> InstOrder;
642
643 // Analyses used.
644 LoopInfo *LI;
645 const LoopAccessInfo &LAI;
646 DominatorTree *DT;
647 BlockFrequencyInfo *BFI;
648 ProfileSummaryInfo *PSI;
649 PredicatedScalarEvolution PSE;
650};
651
652} // end anonymous namespace
653
655 DominatorTree &DT,
659 LoopAccessInfoManager &LAIs) {
660 // Build up a worklist of inner-loops to transform to avoid iterator
661 // invalidation.
662 // FIXME: This logic comes from other passes that actually change the loop
663 // nest structure. It isn't clear this is necessary (or useful) for a pass
664 // which merely optimizes the use of loads in a loop.
665 SmallVector<Loop *, 8> Worklist;
666
667 bool Changed = false;
668
669 for (Loop *TopLevelLoop : LI)
670 for (Loop *L : depth_first(TopLevelLoop)) {
671 Changed |= simplifyLoop(L, &DT, &LI, SE, AC, /*MSSAU*/ nullptr, false);
672 // We only handle inner-most loops.
673 if (L->isInnermost())
674 Worklist.push_back(L);
675 }
676
677 // Now walk the identified inner loops.
678 for (Loop *L : Worklist) {
679 // Match historical behavior
680 if (!L->isRotatedForm() || !L->getExitingBlock())
681 continue;
682 // The actual work is performed by LoadEliminationForLoop.
683 LoadEliminationForLoop LEL(L, &LI, LAIs.getInfo(*L), &DT, BFI, PSI);
684 Changed |= LEL.processLoop();
685 if (Changed)
686 LAIs.clear();
687 }
688 return Changed;
689}
690
693 auto &LI = AM.getResult<LoopAnalysis>(F);
694 // There are no loops in the function. Return before computing other expensive
695 // analyses.
696 if (LI.empty())
697 return PreservedAnalyses::all();
698 auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
699 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
700 auto &AC = AM.getResult<AssumptionAnalysis>(F);
701 auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
702 auto *PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
703 auto *BFI = (PSI && PSI->hasProfileSummary()) ?
704 &AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
706
707 bool Changed = eliminateLoadsAcrossLoops(F, LI, DT, BFI, PSI, &SE, &AC, LAIs);
708
709 if (!Changed)
710 return PreservedAnalyses::all();
711
715 return PA;
716}
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
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:594
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::FlagNone, 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:257
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
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:2094
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:1755
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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:469
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.
LLVM_ABI std::optional< int64_t > getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr, const Loop *Lp, const DominatorTree &DT, const SymbolicStrideMap &StridesMap=SymbolicStrideMap(), bool ShouldCheckWrap=true, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
If the pointer has a constant stride return it in units of the access type size.
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:1807
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:2104
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:2208
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define SEE(c)
Definition regcomp.c:249
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)