llvm.org GIT mirror llvm / 90fe7e7
[PM] Port LoopLoadElimination to the new pass manager and wire it into the main pipeline. This is a very straight forward port. Nothing weird or surprising. This brings the number of missing passes from the new PM's pipeline down to three. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293249 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 2 years ago
7 changed file(s) with 99 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
0 //===---- LoopLoadElimination.h ---------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This header defines the LoopLoadEliminationPass object. This pass forwards
10 /// loaded values around loop backedges to allow their use in subsequent
11 /// iterations.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
16 #define LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
17
18 #include "llvm/IR/PassManager.h"
19
20 namespace llvm {
21
22 /// Pass to forward loads in a loop around the backedge to subsequent
23 /// iterations.
24 struct LoopLoadEliminationPass : public PassInfoMixin {
25 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
26 };
27 }
28
29 #endif // LLVM_TRANSFORMS_SCALAR_LOOPLOADELIMINATION_H
103103 #include "llvm/Transforms/Scalar/LoopDistribute.h"
104104 #include "llvm/Transforms/Scalar/LoopIdiomRecognize.h"
105105 #include "llvm/Transforms/Scalar/LoopInstSimplify.h"
106 #include "llvm/Transforms/Scalar/LoopLoadElimination.h"
106107 #include "llvm/Transforms/Scalar/LoopPassManager.h"
107108 #include "llvm/Transforms/Scalar/LoopPredication.h"
108109 #include "llvm/Transforms/Scalar/LoopRotation.h"
503504 // Now run the core loop vectorizer.
504505 OptimizePM.addPass(LoopVectorizePass());
505506
506 // FIXME: Need to port Loop Load Elimination and add it here.
507 // Eliminate loads by forwarding stores from the previous iteration to loads
508 // of the current iteration.
509 OptimizePM.addPass(LoopLoadEliminationPass());
507510
508511 // Cleanup after the loop optimization passes.
509512 OptimizePM.addPass(InstCombinePass());
169169 FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass())
170170 FUNCTION_PASS("lcssa", LCSSAPass())
171171 FUNCTION_PASS("loop-data-prefetch", LoopDataPrefetchPass())
172 FUNCTION_PASS("loop-load-elim", LoopLoadEliminationPass())
172173 FUNCTION_PASS("loop-distribute", LoopDistributePass())
173174 FUNCTION_PASS("loop-vectorize", LoopVectorizePass())
174175 FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
1919 //
2020 //===----------------------------------------------------------------------===//
2121
22 #include "llvm/Transforms/Scalar/LoopLoadElimination.h"
2223 #include "llvm/ADT/APInt.h"
2324 #include "llvm/ADT/DenseMap.h"
2425 #include "llvm/ADT/DepthFirstIterator.h"
26 #include "llvm/ADT/STLExtras.h"
2527 #include "llvm/ADT/SmallSet.h"
2628 #include "llvm/ADT/SmallVector.h"
2729 #include "llvm/ADT/Statistic.h"
28 #include "llvm/ADT/STLExtras.h"
2930 #include "llvm/Analysis/GlobalsModRef.h"
3031 #include "llvm/Analysis/LoopAccessAnalysis.h"
3132 #include "llvm/Analysis/LoopInfo.h"
4445 #include "llvm/Support/Debug.h"
4546 #include "llvm/Transforms/Scalar.h"
4647 #include "llvm/Transforms/Utils/LoopVersioning.h"
48 #include
49 #include
4750 #include
48 #include
49 #include
5051 #include
5152 #include
5253 #include
557558 PredicatedScalarEvolution PSE;
558559 };
559560
561 static bool
562 eliminateLoadsAcrossLoops(Function &F, LoopInfo &LI, DominatorTree &DT,
563 function_ref GetLAI) {
564 // Build up a worklist of inner-loops to transform to avoid iterator
565 // invalidation.
566 // FIXME: This logic comes from other passes that actually change the loop
567 // nest structure. It isn't clear this is necessary (or useful) for a pass
568 // which merely optimizes the use of loads in a loop.
569 SmallVector Worklist;
570
571 for (Loop *TopLevelLoop : LI)
572 for (Loop *L : depth_first(TopLevelLoop))
573 // We only handle inner-most loops.
574 if (L->empty())
575 Worklist.push_back(L);
576
577 // Now walk the identified inner loops.
578 bool Changed = false;
579 for (Loop *L : Worklist) {
580 // The actual work is performed by LoadEliminationForLoop.
581 LoadEliminationForLoop LEL(L, &LI, GetLAI(*L), &DT);
582 Changed |= LEL.processLoop();
583 }
584 return Changed;
585 }
586
560587 /// \brief The pass. Most of the work is delegated to the per-loop
561588 /// LoadEliminationForLoop class.
562589 class LoopLoadElimination : public FunctionPass {
569596 if (skipFunction(F))
570597 return false;
571598
572 auto *LI = &getAnalysis().getLoopInfo();
573 auto *LAA = &getAnalysis();
574 auto *DT = &getAnalysis().getDomTree();
575
576 // Build up a worklist of inner-loops to vectorize. This is necessary as the
577 // act of distributing a loop creates new loops and can invalidate iterators
578 // across the loops.
579 SmallVector Worklist;
580
581 for (Loop *TopLevelLoop : *LI)
582 for (Loop *L : depth_first(TopLevelLoop))
583 // We only handle inner-most loops.
584 if (L->empty())
585 Worklist.push_back(L);
586
587 // Now walk the identified inner loops.
588 bool Changed = false;
589 for (Loop *L : Worklist) {
590 const LoopAccessInfo &LAI = LAA->getInfo(L);
591 // The actual work is performed by LoadEliminationForLoop.
592 LoadEliminationForLoop LEL(L, LI, LAI, DT);
593 Changed |= LEL.processLoop();
594 }
599 auto &LI = getAnalysis().getLoopInfo();
600 auto &LAA = getAnalysis();
601 auto &DT = getAnalysis().getDomTree();
595602
596603 // Process each loop nest in the function.
597 return Changed;
604 return eliminateLoadsAcrossLoops(
605 F, LI, DT,
606 [&LAA](Loop &L) -> const LoopAccessInfo & { return LAA.getInfo(&L); });
598607 }
599608
600609 void getAnalysisUsage(AnalysisUsage &AU) const override {
630639 return new LoopLoadElimination();
631640 }
632641
642 PreservedAnalyses LoopLoadEliminationPass::run(Function &F,
643 FunctionAnalysisManager &AM) {
644 auto &SE = AM.getResult(F);
645 auto &LI = AM.getResult(F);
646 auto &TTI = AM.getResult(F);
647 auto &DT = AM.getResult(F);
648 auto &TLI = AM.getResult(F);
649 auto &AA = AM.getResult(F);
650 auto &AC = AM.getResult(F);
651
652 auto &LAM = AM.getResult(F).getManager();
653 bool Changed = eliminateLoadsAcrossLoops(
654 F, LI, DT, [&](Loop &L) -> const LoopAccessInfo & {
655 LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE, TLI, TTI};
656 return LAM.getResult(L, AR);
657 });
658
659 if (!Changed)
660 return PreservedAnalyses::all();
661
662 PreservedAnalyses PA;
663 return PA;
664 }
665
633666 } // end namespace llvm
133133 ; CHECK-O-NEXT: Running pass: LoopVectorizePass
134134 ; CHECK-O-NEXT: Running analysis: BlockFrequencyAnalysis
135135 ; CHECK-O-NEXT: Running analysis: BranchProbabilityAnalysis
136 ; CHECK-O-NEXT: Running pass: LoopLoadEliminationPass
137 ; CHECK-O-NEXT: Running analysis: LoopAccessAnalysis
136138 ; CHECK-O-NEXT: Running pass: InstCombinePass
137139 ; CHECK-O-NEXT: Running pass: SLPVectorizerPass
138140 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
0 ; RUN: opt -loop-load-elim -S < %s | FileCheck %s
1 ; RUN: opt -passes=loop-load-elim -S < %s | FileCheck %s
12
23 ; Simple st->ld forwarding derived from a lexical backward dep.
34 ;
0 ; RUN: opt -loop-load-elim -S < %s | FileCheck %s
1 ; RUN: opt -passes=loop-load-elim -S < %s | FileCheck %s
12
23 ; Simple st->ld forwarding derived from a lexical forward dep.
34 ;