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 "ScalarOptions.h"
24#include "llvm/ADT/APInt.h"
25#include "llvm/ADT/DenseMap.h"
27#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/Statistic.h"
43#include "llvm/IR/DataLayout.h"
44#include "llvm/IR/Dominators.h"
46#include "llvm/IR/PassManager.h"
47#include "llvm/IR/Type.h"
48#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
68STATISTIC(NumLoopLoadEliminted, "Number of loads eliminated by LLE");
69
70namespace {
71
72/// Represent a store-to-forwarding candidate.
73struct StoreToLoadForwardingCandidate {
76
77 StoreToLoadForwardingCandidate(LoadInst *Load, StoreInst *Store)
78 : Load(Load), Store(Store) {}
79
80 /// Return true if the dependence from the store to the load has an
81 /// absolute distance of one.
82 /// E.g. A[i+1] = A[i] (or A[i-1] = A[i] for descending loop)
83 bool isDependenceDistanceOfOne(PredicatedScalarEvolution &PSE, Loop *L,
84 const DominatorTree &DT) const {
85 Value *LoadPtr = Load->getPointerOperand();
86 Value *StorePtr = Store->getPointerOperand();
87 Type *LoadType = getLoadStoreType(Load);
88 auto &DL = Load->getDataLayout();
89
91 StorePtr->getType()->getPointerAddressSpace() &&
92 DL.getTypeSizeInBits(LoadType) ==
93 DL.getTypeSizeInBits(getLoadStoreType(Store)) &&
94 "Should be a known dependence");
95
96 int64_t StrideLoad =
97 getPtrStride(PSE, LoadType, LoadPtr, L, DT).value_or(0);
98 int64_t StrideStore =
99 getPtrStride(PSE, LoadType, StorePtr, L, DT).value_or(0);
100 if (!StrideLoad || !StrideStore || StrideLoad != StrideStore)
101 return false;
102
103 // TODO: This check for stride values other than 1 and -1 can be eliminated.
104 // However, doing so may cause the LoopAccessAnalysis to overcompensate,
105 // generating numerous non-wrap runtime checks that may undermine the
106 // benefits of load elimination. To safely implement support for non-unit
107 // strides, we would need to ensure either that the processed case does not
108 // require these additional checks, or improve the LAA to handle them more
109 // efficiently, or potentially both.
110 if (std::abs(StrideLoad) != 1)
111 return false;
112
113 unsigned TypeByteSize = DL.getTypeAllocSize(LoadType);
114
115 auto *LoadPtrSCEV = cast<SCEVAddRecExpr>(PSE.getSCEV(LoadPtr));
116 auto *StorePtrSCEV = cast<SCEVAddRecExpr>(PSE.getSCEV(StorePtr));
117
118 // We don't need to check non-wrapping here because forward/backward
119 // dependence wouldn't be valid if these weren't monotonic accesses.
120 auto *Dist = dyn_cast<SCEVConstant>(
121 PSE.getSE()->getMinusSCEV(StorePtrSCEV, LoadPtrSCEV));
122 if (!Dist)
123 return false;
124 const APInt &Val = Dist->getAPInt();
125 return Val == TypeByteSize * StrideLoad;
126 }
127
128 Value *getLoadPtr() const { return Load->getPointerOperand(); }
129
130#ifndef NDEBUG
131 friend raw_ostream &operator<<(raw_ostream &OS,
132 const StoreToLoadForwardingCandidate &Cand) {
133 OS << *Cand.Store << " -->\n";
134 OS.indent(2) << *Cand.Load << "\n";
135 return OS;
136 }
137#endif
138};
139
140} // end anonymous namespace
141
142/// Check if the store dominates all latches, so as long as there is no
143/// intervening store this value will be loaded in the next iteration.
144static bool doesStoreDominatesAllLatches(BasicBlock *StoreBlock, Loop *L,
145 DominatorTree *DT) {
147 L->getLoopLatches(Latches);
148 return llvm::all_of(Latches, [&](const BasicBlock *Latch) {
149 return DT->dominates(StoreBlock, Latch);
150 });
151}
152
153/// Return true if the load is not executed on all paths in the loop.
155 return Load->getParent() != L->getHeader();
156}
157
158namespace {
159
160/// The per-loop class that does most of the work.
161class LoadEliminationForLoop {
162public:
163 LoadEliminationForLoop(Loop *L, LoopInfo *LI, const LoopAccessInfo &LAI,
164 DominatorTree *DT, BlockFrequencyInfo *BFI,
165 ProfileSummaryInfo* PSI)
166 : L(L), LI(LI), LAI(LAI), DT(DT), BFI(BFI), PSI(PSI), PSE(LAI.getPSE()) {}
167
168 /// Look through the loop-carried and loop-independent dependences in
169 /// this loop and find store->load dependences.
170 ///
171 /// Note that no candidate is returned if LAA has failed to analyze the loop
172 /// (e.g. if it's not bottom-tested, contains volatile memops, etc.)
173 std::forward_list<StoreToLoadForwardingCandidate>
174 findStoreToLoadDependences(const LoopAccessInfo &LAI) {
175 std::forward_list<StoreToLoadForwardingCandidate> Candidates;
176
177 const auto &DepChecker = LAI.getDepChecker();
178 const auto *Deps = DepChecker.getDependences();
179 if (!Deps)
180 return Candidates;
181
182 // Find store->load dependences (consequently true dep). Both lexically
183 // forward and backward dependences qualify.
184 // Disqualify loads that have other unsafe dependences.
185
186 SmallPtrSet<Instruction *, 4> LoadsWithUnsafeDependence;
187
188 for (const auto &Dep : *Deps) {
189 Instruction *Source = Dep.getSource(DepChecker);
190 Instruction *Destination = Dep.getDestination(DepChecker);
191
195 if (isa<LoadInst>(Source))
196 LoadsWithUnsafeDependence.insert(Source);
197 if (isa<LoadInst>(Destination))
198 LoadsWithUnsafeDependence.insert(Destination);
199 continue;
200 }
201
202 if (Dep.isBackward())
203 // Note that the designations source and destination follow the program
204 // order, i.e. source is always first. (The direction is given by the
205 // DepType.)
206 std::swap(Source, Destination);
207 else
208 assert(Dep.isForward() && "Needs to be a forward dependence");
209
210 auto *Store = dyn_cast<StoreInst>(Source);
211 if (!Store)
212 continue;
213 auto *Load = dyn_cast<LoadInst>(Destination);
214 if (!Load)
215 continue;
216
217 // Only propagate if the stored values are bit/pointer castable.
220 Store->getDataLayout())) {
221 // This store may partially clobber the value from another forwarding
222 // candidate.
223 LoadsWithUnsafeDependence.insert(Load);
224 continue;
225 }
226
227 Candidates.emplace_front(Load, Store);
228 }
229
230 if (!LoadsWithUnsafeDependence.empty())
231 Candidates.remove_if([&](const StoreToLoadForwardingCandidate &C) {
232 return LoadsWithUnsafeDependence.count(C.Load);
233 });
234
235 return Candidates;
236 }
237
238 /// Return the index of the instruction according to program order.
239 unsigned getInstrIndex(Instruction *Inst) {
240 auto I = InstOrder.find(Inst);
241 assert(I != InstOrder.end() && "No index for instruction");
242 return I->second;
243 }
244
245 /// If a load has multiple candidates associated (i.e. different
246 /// stores), it means that it could be forwarding from multiple stores
247 /// depending on control flow. Remove these candidates.
248 ///
249 /// Here, we rely on LAA to include the relevant loop-independent dependences.
250 /// LAA is known to omit these in the very simple case when the read and the
251 /// write within an alias set always takes place using the *same* pointer.
252 ///
253 /// However, we know that this is not the case here, i.e. we can rely on LAA
254 /// to provide us with loop-independent dependences for the cases we're
255 /// interested. Consider the case for example where a loop-independent
256 /// dependece S1->S2 invalidates the forwarding S3->S2.
257 ///
258 /// A[i] = ... (S1)
259 /// ... = A[i] (S2)
260 /// A[i+1] = ... (S3)
261 ///
262 /// LAA will perform dependence analysis here because there are two
263 /// *different* pointers involved in the same alias set (&A[i] and &A[i+1]).
264 void removeDependencesFromMultipleStores(
265 std::forward_list<StoreToLoadForwardingCandidate> &Candidates) {
266 // If Store is nullptr it means that we have multiple stores forwarding to
267 // this store.
268 using LoadToSingleCandT =
269 DenseMap<LoadInst *, const StoreToLoadForwardingCandidate *>;
270 LoadToSingleCandT LoadToSingleCand;
271
272 for (const auto &Cand : Candidates) {
273 bool NewElt;
274 LoadToSingleCandT::iterator Iter;
275
276 std::tie(Iter, NewElt) =
277 LoadToSingleCand.insert(std::make_pair(Cand.Load, &Cand));
278 if (!NewElt) {
279 const StoreToLoadForwardingCandidate *&OtherCand = Iter->second;
280 // Already multiple stores forward to this load.
281 if (OtherCand == nullptr)
282 continue;
283
284 // Handle the very basic case when the two stores are in the same block
285 // so deciding which one forwards is easy. The later one forwards as
286 // long as they both have a dependence distance of one to the load.
287 if (Cand.Store->getParent() == OtherCand->Store->getParent() &&
288 Cand.isDependenceDistanceOfOne(PSE, L, *DT) &&
289 OtherCand->isDependenceDistanceOfOne(PSE, L, *DT)) {
290 // They are in the same block, the later one will forward to the load.
291 if (getInstrIndex(OtherCand->Store) < getInstrIndex(Cand.Store))
292 OtherCand = &Cand;
293 } else
294 OtherCand = nullptr;
295 }
296 }
297
298 Candidates.remove_if([&](const StoreToLoadForwardingCandidate &Cand) {
299 if (LoadToSingleCand[Cand.Load] != &Cand) {
301 dbgs() << "Removing from candidates: \n"
302 << Cand
303 << " The load may have multiple stores forwarding to "
304 << "it\n");
305 return true;
306 }
307 return false;
308 });
309 }
310
311 /// Given two pointers operations by their RuntimePointerChecking
312 /// indices, return true if they require an alias check.
313 ///
314 /// We need a check if one is a pointer for a candidate load and the other is
315 /// a pointer for a possibly intervening store.
316 bool needsChecking(unsigned PtrIdx1, unsigned PtrIdx2,
317 const SmallPtrSetImpl<Value *> &PtrsWrittenOnFwdingPath,
318 const SmallPtrSetImpl<Value *> &CandLoadPtrs) {
319 Value *Ptr1 =
320 LAI.getRuntimePointerChecking()->getPointerInfo(PtrIdx1).PointerValue;
321 Value *Ptr2 =
322 LAI.getRuntimePointerChecking()->getPointerInfo(PtrIdx2).PointerValue;
323 return ((PtrsWrittenOnFwdingPath.count(Ptr1) && CandLoadPtrs.count(Ptr2)) ||
324 (PtrsWrittenOnFwdingPath.count(Ptr2) && CandLoadPtrs.count(Ptr1)));
325 }
326
327 /// Return pointers that are possibly written to on the path from a
328 /// forwarding store to a load.
329 ///
330 /// These pointers need to be alias-checked against the forwarding candidates.
331 SmallPtrSet<Value *, 4> findPointersWrittenOnForwardingPath(
332 const SmallVectorImpl<StoreToLoadForwardingCandidate> &Candidates) {
333 // From FirstStore to LastLoad neither of the elimination candidate loads
334 // should overlap with any of the stores.
335 //
336 // E.g.:
337 //
338 // st1 C[i]
339 // ld1 B[i] <-------,
340 // ld0 A[i] <----, | * LastLoad
341 // ... | |
342 // st2 E[i] | |
343 // st3 B[i+1] -- | -' * FirstStore
344 // st0 A[i+1] ---'
345 // st4 D[i]
346 //
347 // st0 forwards to ld0 if the accesses in st4 and st1 don't overlap with
348 // ld0.
349
350 LoadInst *LastLoad =
351 llvm::max_element(Candidates,
352 [&](const StoreToLoadForwardingCandidate &A,
353 const StoreToLoadForwardingCandidate &B) {
354 return getInstrIndex(A.Load) <
355 getInstrIndex(B.Load);
356 })
357 ->Load;
358 StoreInst *FirstStore =
359 llvm::min_element(Candidates,
360 [&](const StoreToLoadForwardingCandidate &A,
361 const StoreToLoadForwardingCandidate &B) {
362 return getInstrIndex(A.Store) <
363 getInstrIndex(B.Store);
364 })
365 ->Store;
366
367 // We're looking for stores after the first forwarding store until the end
368 // of the loop, then from the beginning of the loop until the last
369 // forwarded-to load. Collect the pointer for the stores.
370 SmallPtrSet<Value *, 4> PtrsWrittenOnFwdingPath;
371
372 auto InsertStorePtr = [&](Instruction *I) {
373 if (auto *S = dyn_cast<StoreInst>(I))
374 PtrsWrittenOnFwdingPath.insert(S->getPointerOperand());
375 };
376 const auto &MemInstrs = LAI.getDepChecker().getMemoryInstructions();
377 std::for_each(MemInstrs.begin() + getInstrIndex(FirstStore) + 1,
378 MemInstrs.end(), InsertStorePtr);
379 std::for_each(MemInstrs.begin(), &MemInstrs[getInstrIndex(LastLoad)],
380 InsertStorePtr);
381
382 return PtrsWrittenOnFwdingPath;
383 }
384
385 /// Determine the pointer alias checks to prove that there are no
386 /// intervening stores.
387 SmallVector<RuntimePointerCheck, 4> collectMemchecks(
388 const SmallVectorImpl<StoreToLoadForwardingCandidate> &Candidates) {
389
390 SmallPtrSet<Value *, 4> PtrsWrittenOnFwdingPath =
391 findPointersWrittenOnForwardingPath(Candidates);
392
393 // Collect the pointers of the candidate loads.
394 SmallPtrSet<Value *, 4> CandLoadPtrs;
395 for (const auto &Candidate : Candidates)
396 CandLoadPtrs.insert(Candidate.getLoadPtr());
397
398 const auto &AllChecks = LAI.getRuntimePointerChecking()->getChecks();
399 SmallVector<RuntimePointerCheck, 4> Checks;
400
401 copy_if(AllChecks, std::back_inserter(Checks),
402 [&](const RuntimePointerCheck &Check) {
403 for (auto PtrIdx1 : Check.first->Members)
404 for (auto PtrIdx2 : Check.second->Members)
405 if (needsChecking(PtrIdx1, PtrIdx2, PtrsWrittenOnFwdingPath,
406 CandLoadPtrs))
407 return true;
408 return false;
409 });
410
411 LLVM_DEBUG(dbgs() << "\nPointer Checks (count: " << Checks.size()
412 << "):\n");
413 LLVM_DEBUG(LAI.getRuntimePointerChecking()->printChecks(dbgs(), Checks));
414
415 return Checks;
416 }
417
418 /// Perform the transformation for a candidate.
419 void
420 propagateStoredValueToLoadUsers(const StoreToLoadForwardingCandidate &Cand,
421 SCEVExpander &SEE) {
422 // loop:
423 // %x = load %gep_i
424 // = ... %x
425 // store %y, %gep_i_plus_1
426 //
427 // =>
428 //
429 // ph:
430 // %x.initial = load %gep_0
431 // loop:
432 // %x.storeforward = phi [%x.initial, %ph] [%y, %loop]
433 // %x = load %gep_i <---- now dead
434 // = ... %x.storeforward
435 // store %y, %gep_i_plus_1
436
437 Value *Ptr = Cand.Load->getPointerOperand();
438 auto *PtrSCEV = cast<SCEVAddRecExpr>(PSE.getSCEV(Ptr));
439 auto *PH = L->getLoopPreheader();
440 assert(PH && "Preheader should exist!");
441 Value *InitialPtr = SEE.expandCodeFor(PtrSCEV->getStart(), Ptr->getType(),
442 PH->getTerminator());
444 new LoadInst(Cand.Load->getType(), InitialPtr, "load_initial",
445 /* isVolatile */ false, Cand.Load->getAlign(),
446 PH->getTerminator()->getIterator());
447 // We don't give any debug location to Initial, because it is inserted
448 // into the loop's preheader. A debug location inside the loop will cause
449 // a misleading stepping when debugging. The test update-debugloc-store
450 // -forwarded.ll checks this.
451 Initial->setDebugLoc(DebugLoc::getDropped());
452
453 PHINode *PHI = PHINode::Create(Initial->getType(), 2, "store_forwarded");
454 PHI->insertBefore(L->getHeader()->begin());
455 PHI->addIncoming(Initial, PH);
456
457 Type *LoadType = Initial->getType();
458 Type *StoreType = Cand.Store->getValueOperand()->getType();
459 auto &DL = Cand.Load->getDataLayout();
460 (void)DL;
461
462 assert(DL.getTypeSizeInBits(LoadType) == DL.getTypeSizeInBits(StoreType) &&
463 "The type sizes should match!");
464
465 Value *StoreValue = Cand.Store->getValueOperand();
466 if (LoadType != StoreType) {
467 StoreValue = CastInst::CreateBitOrPointerCast(StoreValue, LoadType,
468 "store_forward_cast",
469 Cand.Store->getIterator());
470 // Because it casts the old `load` value and is used by the new `phi`
471 // which replaces the old `load`, we give the `load`'s debug location
472 // to it.
473 cast<Instruction>(StoreValue)->setDebugLoc(Cand.Load->getDebugLoc());
474 }
475
476 PHI->addIncoming(StoreValue, L->getLoopLatch());
477
478 Cand.Load->replaceAllUsesWith(PHI);
479 PHI->setDebugLoc(Cand.Load->getDebugLoc());
480 }
481
482 /// Top-level driver for each loop: find store->load forwarding
483 /// candidates, add run-time checks and perform transformation.
484 bool processLoop() {
485 const ScalarOptions &Opts = ScalarOptions::Global;
486 LLVM_DEBUG(dbgs() << "\nIn \"" << L->getHeader()->getParent()->getName()
487 << "\" checking " << *L << "\n");
488
489 // Look for store-to-load forwarding cases across the
490 // backedge. E.g.:
491 //
492 // loop:
493 // %x = load %gep_i
494 // = ... %x
495 // store %y, %gep_i_plus_1
496 //
497 // =>
498 //
499 // ph:
500 // %x.initial = load %gep_0
501 // loop:
502 // %x.storeforward = phi [%x.initial, %ph] [%y, %loop]
503 // %x = load %gep_i <---- now dead
504 // = ... %x.storeforward
505 // store %y, %gep_i_plus_1
506
507 // First start with store->load dependences.
508 auto StoreToLoadDependences = findStoreToLoadDependences(LAI);
509 if (StoreToLoadDependences.empty())
510 return false;
511
512 // Generate an index for each load and store according to the original
513 // program order. This will be used later.
514 InstOrder = LAI.getDepChecker().generateInstructionOrderMap();
515
516 // To keep things simple for now, remove those where the load is potentially
517 // fed by multiple stores.
518 removeDependencesFromMultipleStores(StoreToLoadDependences);
519 if (StoreToLoadDependences.empty())
520 return false;
521
522 // Filter the candidates further.
524 for (const StoreToLoadForwardingCandidate &Cand : StoreToLoadDependences) {
525 LLVM_DEBUG(dbgs() << "Candidate " << Cand);
526
527 // Make sure that the stored values is available everywhere in the loop in
528 // the next iteration.
529 if (!doesStoreDominatesAllLatches(Cand.Store->getParent(), L, DT))
530 continue;
531
532 // If the load is conditional we can't hoist its 0-iteration instance to
533 // the preheader because that would make it unconditional. Thus we would
534 // access a memory location that the original loop did not access.
535 if (isLoadConditional(Cand.Load, L))
536 continue;
537
538 // Check whether the SCEV difference is the same as the induction step,
539 // thus we load the value in the next iteration.
540 if (!Cand.isDependenceDistanceOfOne(PSE, L, *DT))
541 continue;
542
543 assert(isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Load->getPointerOperand())) &&
544 "Loading from something other than indvar?");
545 assert(
546 isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Store->getPointerOperand())) &&
547 "Storing to something other than indvar?");
548
549 Candidates.push_back(Cand);
551 dbgs()
552 << Candidates.size()
553 << ". Valid store-to-load forwarding across the loop backedge\n");
554 }
555 if (Candidates.empty())
556 return false;
557
558 // Check intervening may-alias stores. These need runtime checks for alias
559 // disambiguation.
560 SmallVector<RuntimePointerCheck, 4> Checks = collectMemchecks(Candidates);
561
562 // Too many checks are likely to outweigh the benefits of forwarding.
563 if (Checks.size() >
564 Candidates.size() * Opts.runtime_check_per_loop_load_elim) {
565 LLVM_DEBUG(dbgs() << "Too many run-time checks needed.\n");
566 return false;
567 }
568
569 if (LAI.getPSE().getPredicate().getComplexity() >
570 Opts.loop_load_elimination_scev_check_threshold) {
571 LLVM_DEBUG(dbgs() << "Too many SCEV run-time checks needed.\n");
572 return false;
573 }
574
575 if (!L->isLoopSimplifyForm()) {
576 LLVM_DEBUG(dbgs() << "Loop is not is loop-simplify form");
577 return false;
578 }
579
580 if (!Checks.empty() || !LAI.getPSE().getPredicate().isAlwaysTrue()) {
581 if (LAI.hasConvergentOp()) {
582 LLVM_DEBUG(dbgs() << "Versioning is needed but not allowed with "
583 "convergent calls\n");
584 return false;
585 }
586
587 auto *HeaderBB = L->getHeader();
588 if (llvm::shouldOptimizeForSize(HeaderBB, PSI, BFI,
589 PGSOQueryType::IRPass)) {
591 dbgs() << "Versioning is needed but not allowed when optimizing "
592 "for size.\n");
593 return false;
594 }
595
596 // Point of no-return, start the transformation. First, version the loop
597 // if necessary.
598
599 // Forming LCSSA is a precondition of versioning.
600 if (!L->isRecursivelyLCSSAForm(*DT, *LI))
601 formLCSSARecursively(*L, *DT, LI, PSE.getSE());
602
603 LoopVersioning LV(LAI, Checks, L, LI, DT, PSE.getSE());
604 LV.versionLoop();
605
606 // After versioning, some of the candidates' pointers could stop being
607 // SCEVAddRecs. We need to filter them out.
608 auto NoLongerGoodCandidate = [this](
609 const StoreToLoadForwardingCandidate &Cand) {
610 return !isa<SCEVAddRecExpr>(
611 PSE.getSCEV(Cand.Load->getPointerOperand())) ||
613 PSE.getSCEV(Cand.Store->getPointerOperand()));
614 };
615 llvm::erase_if(Candidates, NoLongerGoodCandidate);
616 }
617
618 // Next, propagate the value stored by the store to the users of the load.
619 // Also for the first iteration, generate the initial value of the load.
620 SCEVExpander SEE(*PSE.getSE(), "storeforward");
621 for (const auto &Cand : Candidates)
622 propagateStoredValueToLoadUsers(Cand, SEE);
623 NumLoopLoadEliminted += Candidates.size();
624
625 return true;
626 }
627
628private:
629 Loop *L;
630
631 /// Maps the load/store instructions to their index according to
632 /// program order.
633 DenseMap<Instruction *, unsigned> InstOrder;
634
635 // Analyses used.
636 LoopInfo *LI;
637 const LoopAccessInfo &LAI;
638 DominatorTree *DT;
639 BlockFrequencyInfo *BFI;
640 ProfileSummaryInfo *PSI;
641 PredicatedScalarEvolution PSE;
642};
643
644} // end anonymous namespace
645
647 DominatorTree &DT,
651 LoopAccessInfoManager &LAIs) {
652 // Build up a worklist of inner-loops to transform to avoid iterator
653 // invalidation.
654 // FIXME: This logic comes from other passes that actually change the loop
655 // nest structure. It isn't clear this is necessary (or useful) for a pass
656 // which merely optimizes the use of loads in a loop.
657 SmallVector<Loop *, 8> Worklist;
658
659 bool Changed = false;
660
661 for (Loop *TopLevelLoop : LI)
662 for (Loop *L : depth_first(TopLevelLoop)) {
663 Changed |= simplifyLoop(L, &DT, &LI, SE, AC, /*MSSAU*/ nullptr, false);
664 // We only handle inner-most loops.
665 if (L->isInnermost())
666 Worklist.push_back(L);
667 }
668
669 // Now walk the identified inner loops.
670 for (Loop *L : Worklist) {
671 // Match historical behavior
672 if (!L->isRotatedForm() || !L->getExitingBlock())
673 continue;
674 // The actual work is performed by LoadEliminationForLoop.
675 LoadEliminationForLoop LEL(L, &LI, LAIs.getInfo(*L), &DT, BFI, PSI);
676 Changed |= LEL.processLoop();
677 if (Changed)
678 LAIs.clear();
679 }
680 return Changed;
681}
682
685 auto &LI = AM.getResult<LoopAnalysis>(F);
686 // There are no loops in the function. Return before computing other expensive
687 // analyses.
688 if (LI.empty())
689 return PreservedAnalyses::all();
690 auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
691 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
692 auto &AC = AM.getResult<AssumptionAnalysis>(F);
693 auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
694 auto *PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
695 auto *BFI = (PSI && PSI->hasProfileSummary()) ?
696 &AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
698
699 bool Changed = eliminateLoadsAcrossLoops(F, LI, DT, BFI, PSI, &SE, &AC, LAIs);
700
701 if (!Changed)
702 return PreservedAnalyses::all();
703
707 return PA;
708}
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 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...
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, SCEVFlags 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
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)