llvm.org GIT mirror llvm / 9b7ecbe
[LoopDist] Port to new PM Summary: The direct motivation for the port is to ensure that the OptRemarkEmitter tests work with the new PM. This remains a function pass because we not only create multiple loops but could also version the original loop. In the test I need to invoke opt with -passes='require<aa>,loop-distribute'. LoopDistribute does not directly depend on AA however LAA does. LAA uses getCachedResult so I *think* we need manually pull in 'aa'. Reviewers: davidxl, silvas Subscribers: sanjoy, llvm-commits, mzolotukhin Differential Revision: https://reviews.llvm.org/D22437 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275811 91177308-0d34-0410-b5e6-96231b3b80d8 Adam Nemet 4 years ago
8 changed file(s) with 120 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
176176 void initializeLoopAccessLegacyAnalysisPass(PassRegistry&);
177177 void initializeLoopDataPrefetchPass(PassRegistry&);
178178 void initializeLoopDeletionLegacyPassPass(PassRegistry&);
179 void initializeLoopDistributePass(PassRegistry&);
179 void initializeLoopDistributeLegacyPass(PassRegistry&);
180180 void initializeLoopExtractorPass(PassRegistry&);
181181 void initializeLoopIdiomRecognizeLegacyPassPass(PassRegistry&);
182182 void initializeLoopInfoWrapperPassPass(PassRegistry&);
0 //===- LoopDistribute.cpp - Loop Distribution Pass --------------*- 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 //
9 // This file implements the Loop Distribution Pass. Its main focus is to
10 // distribute loops that cannot be vectorized due to dependence cycles. It
11 // tries to isolate the offending dependences into a new loop allowing
12 // vectorization of the remaining parts.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_TRANSFORMS_SCALAR_LOOPDISTRIBUTE_H
17 #define LLVM_TRANSFORMS_SCALAR_LOOPDISTRIBUTE_H
18
19 #include "llvm/IR/PassManager.h"
20
21 namespace llvm {
22
23 class LoopDistributePass : public PassInfoMixin {
24 public:
25 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
26 };
27 } // end namespace llvm
28
29 #endif // LLVM_TRANSFORMS_SCALAR_LOOPDISTRIBUTE_H
9191 #include "llvm/Transforms/Scalar/JumpThreading.h"
9292 #include "llvm/Transforms/Scalar/LICM.h"
9393 #include "llvm/Transforms/Scalar/LoopDeletion.h"
94 #include "llvm/Transforms/Scalar/LoopDistribute.h"
9495 #include "llvm/Transforms/Scalar/LoopIdiomRecognize.h"
9596 #include "llvm/Transforms/Scalar/LoopInstSimplify.h"
9697 #include "llvm/Transforms/Scalar/LoopRotation.h"
150150 FUNCTION_PASS("jump-threading", JumpThreadingPass())
151151 FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass())
152152 FUNCTION_PASS("lcssa", LCSSAPass())
153 FUNCTION_PASS("loop-distribute", LoopDistributePass())
153154 FUNCTION_PASS("loop-vectorize", LoopVectorizePass())
154155 FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
155156 FUNCTION_PASS("print", AssumptionPrinterPass(dbgs()))
2121 //
2222 //===----------------------------------------------------------------------===//
2323
24 #include "llvm/Transforms/Scalar/LoopDistribute.h"
2425 #include "llvm/ADT/DepthFirstIterator.h"
2526 #include "llvm/ADT/EquivalenceClasses.h"
2627 #include "llvm/ADT/STLExtras.h"
2829 #include "llvm/Analysis/BlockFrequencyInfo.h"
2930 #include "llvm/Analysis/LoopAccessAnalysis.h"
3031 #include "llvm/Analysis/LoopInfo.h"
32 #include "llvm/Analysis/LoopPassManager.h"
3133 #include "llvm/Analysis/OptimizationDiagnosticInfo.h"
3234 #include "llvm/IR/DiagnosticInfo.h"
3335 #include "llvm/IR/Dominators.h"
596598 }
597599
598600 /// \brief Try to distribute an inner-most loop.
599 bool processLoop(LoopAccessLegacyAnalysis *LAA) {
601 bool processLoop(std::function &GetLAA) {
600602 assert(L->empty() && "Only process inner loops.");
601603
602604 DEBUG(dbgs() << "\nLDist: In \"" << L->getHeader()->getParent()->getName()
609611 return fail("multiple exit blocks");
610612
611613 // LAA will check that we only have a single exiting block.
612 LAI = &LAA->getInfo(L);
614 LAI = &GetLAA(*L);
613615
614616 // Currently, we only distribute to isolate the part of the loop with
615617 // dependence cycles to enable partial vectorization.
859861 Optional IsForced;
860862 };
861863
864 /// Shared implementation between new and old PMs.
865 static bool runImpl(Function &F, LoopInfo *LI, DominatorTree *DT,
866 ScalarEvolution *SE, OptimizationRemarkEmitter *ORE,
867 std::function &GetLAA,
868 bool ProcessAllLoops) {
869 // Build up a worklist of inner-loops to vectorize. This is necessary as the
870 // act of distributing a loop creates new loops and can invalidate iterators
871 // across the loops.
872 SmallVector Worklist;
873
874 for (Loop *TopLevelLoop : *LI)
875 for (Loop *L : depth_first(TopLevelLoop))
876 // We only handle inner-most loops.
877 if (L->empty())
878 Worklist.push_back(L);
879
880 // Now walk the identified inner loops.
881 bool Changed = false;
882 for (Loop *L : Worklist) {
883 LoopDistributeForLoop LDL(L, &F, LI, DT, SE, ORE);
884
885 // If distribution was forced for the specific loop to be
886 // enabled/disabled, follow that. Otherwise use the global flag.
887 if (LDL.isForced().getValueOr(ProcessAllLoops))
888 Changed |= LDL.processLoop(GetLAA);
889 }
890
891 // Process each loop nest in the function.
892 return Changed;
893 }
894
862895 /// \brief The pass class.
863 class LoopDistribute : public FunctionPass {
896 class LoopDistributeLegacy : public FunctionPass {
864897 public:
865898 /// \p ProcessAllLoopsByDefault specifies whether loop distribution should be
866899 /// performed by default. Pass -enable-loop-distribute={0,1} overrides this
867900 /// default. We use this to keep LoopDistribution off by default when invoked
868901 /// from the optimization pipeline but on when invoked explicitly from opt.
869 LoopDistribute(bool ProcessAllLoopsByDefault = true)
902 LoopDistributeLegacy(bool ProcessAllLoopsByDefault = true)
870903 : FunctionPass(ID), ProcessAllLoops(ProcessAllLoopsByDefault) {
871904 // The default is set by the caller.
872905 if (EnableLoopDistribute.getNumOccurrences() > 0)
873906 ProcessAllLoops = EnableLoopDistribute;
874 initializeLoopDistributePass(*PassRegistry::getPassRegistry());
907 initializeLoopDistributeLegacyPass(*PassRegistry::getPassRegistry());
875908 }
876909
877910 bool runOnFunction(Function &F) override {
883916 auto *DT = &getAnalysis().getDomTree();
884917 auto *SE = &getAnalysis().getSE();
885918 auto *ORE = &getAnalysis().getORE();
886
887 // Build up a worklist of inner-loops to vectorize. This is necessary as the
888 // act of distributing a loop creates new loops and can invalidate iterators
889 // across the loops.
890 SmallVector Worklist;
891
892 for (Loop *TopLevelLoop : *LI)
893 for (Loop *L : depth_first(TopLevelLoop))
894 // We only handle inner-most loops.
895 if (L->empty())
896 Worklist.push_back(L);
897
898 // Now walk the identified inner loops.
899 bool Changed = false;
900 for (Loop *L : Worklist) {
901 LoopDistributeForLoop LDL(L, &F, LI, DT, SE, ORE);
902
903 // If distribution was forced for the specific loop to be
904 // enabled/disabled, follow that. Otherwise use the global flag.
905 if (LDL.isForced().getValueOr(ProcessAllLoops))
906 Changed |= LDL.processLoop(LAA);
907 }
908
909 // Process each loop nest in the function.
910 return Changed;
919 std::function GetLAA =
920 [&](Loop &L) -> const LoopAccessInfo & { return LAA->getInfo(&L); };
921
922 return runImpl(F, LI, DT, SE, ORE, GetLAA, ProcessAllLoops);
911923 }
912924
913925 void getAnalysisUsage(AnalysisUsage &AU) const override {
929941 };
930942 } // anonymous namespace
931943
932 char LoopDistribute::ID;
944 PreservedAnalyses LoopDistributePass::run(Function &F,
945 FunctionAnalysisManager &AM) {
946 // FIXME: This does not currently match the behavior from the old PM.
947 // ProcessAllLoops with the old PM defaults to true when invoked from opt and
948 // false when invoked from the optimization pipeline.
949 bool ProcessAllLoops = false;
950 if (EnableLoopDistribute.getNumOccurrences() > 0)
951 ProcessAllLoops = EnableLoopDistribute;
952
953 auto &LI = AM.getResult(F);
954 auto &DT = AM.getResult(F);
955 auto &SE = AM.getResult(F);
956 auto &ORE = AM.getResult(F);
957
958 auto &LAM = AM.getResult(F).getManager();
959 std::function GetLAA =
960 [&](Loop &L) -> const LoopAccessInfo & {
961 return LAM.getResult(L);
962 };
963
964 bool Changed = runImpl(F, &LI, &DT, &SE, &ORE, GetLAA, ProcessAllLoops);
965 if (!Changed)
966 return PreservedAnalyses::all();
967 PreservedAnalyses PA;
968 PA.preserve();
969 PA.preserve();
970 return PA;
971 }
972
973 char LoopDistributeLegacy::ID;
933974 static const char ldist_name[] = "Loop Distribition";
934975
935 INITIALIZE_PASS_BEGIN(LoopDistribute, LDIST_NAME, ldist_name, false, false)
976 INITIALIZE_PASS_BEGIN(LoopDistributeLegacy, LDIST_NAME, ldist_name, false,
977 false)
936978 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
937979 INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis)
938980 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
939981 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
940982 INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
941 INITIALIZE_PASS_END(LoopDistribute, LDIST_NAME, ldist_name, false, false)
983 INITIALIZE_PASS_END(LoopDistributeLegacy, LDIST_NAME, ldist_name, false, false)
942984
943985 namespace llvm {
944986 FunctionPass *createLoopDistributePass(bool ProcessAllLoopsByDefault) {
945 return new LoopDistribute(ProcessAllLoopsByDefault);
987 return new LoopDistributeLegacy(ProcessAllLoopsByDefault);
946988 }
947989 }
8585 initializePlaceBackedgeSafepointsImplPass(Registry);
8686 initializePlaceSafepointsPass(Registry);
8787 initializeFloat2IntLegacyPassPass(Registry);
88 initializeLoopDistributePass(Registry);
88 initializeLoopDistributeLegacyPass(Registry);
8989 initializeLoopLoadEliminationPass(Registry);
9090 initializeLoopSimplifyCFGLegacyPassPass(Registry);
9191 initializeLoopVersioningPassPass(Registry);
22 ; RUN: opt -loop-distribute -S -pass-remarks-missed=loop-distribute \
33 ; RUN: -debug-only=block-freq -pass-remarks-with-hotness < %s 2>&1 | FileCheck %s --check-prefix=HOTNESS
44 ; RUN: opt -loop-distribute -S -pass-remarks-missed=loop-distribute \
5 ; RUN: -debug-only=block-freq < %s 2>&1 | FileCheck %s --check-prefix=NO_HOTNESS
6
7 ; RUN: opt -passes='require,loop-distribute' -S -pass-remarks-missed=loop-distribute \
8 ; RUN: -debug-only=block-freq -pass-remarks-with-hotness < %s 2>&1 | FileCheck %s --check-prefix=HOTNESS
9 ; RUN: opt -passes='require,loop-distribute' -S -pass-remarks-missed=loop-distribute \
510 ; RUN: -debug-only=block-freq < %s 2>&1 | FileCheck %s --check-prefix=NO_HOTNESS
611
712 ; REQUIRES: asserts
0 ; RUN: opt -loop-distribute -S -pass-remarks-missed=loop-distribute \
11 ; RUN: -pass-remarks-with-hotness < %s 2>&1 | FileCheck %s --check-prefix=HOTNESS
22 ; RUN: opt -loop-distribute -S -pass-remarks-missed=loop-distribute \
3 ; RUN: < %s 2>&1 | FileCheck %s --check-prefix=NO_HOTNESS
4
5 ; RUN: opt -passes='require,loop-distribute' -S -pass-remarks-missed=loop-distribute \
6 ; RUN: -pass-remarks-with-hotness < %s 2>&1 | FileCheck %s --check-prefix=HOTNESS
7 ; RUN: opt -passes='require,loop-distribute' -S -pass-remarks-missed=loop-distribute \
38 ; RUN: < %s 2>&1 | FileCheck %s --check-prefix=NO_HOTNESS
49
510 ; REQUIRES: asserts