From 1eca6bc6a7f0c29bb155cfb42775738cdd582e98 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Sat, 13 Aug 2016 04:11:27 +0000 Subject: [PM] Port LoopDataPrefetch to new pass manager Summary: Refactor the existing support into a LoopDataPrefetch implementation class and a LoopDataPrefetchLegacyPass class that invokes it. Add a new LoopDataPrefetchPass for the new pass manager that utilizes the LoopDataPrefetch implementation class. Reviewers: mehdi_amini Subscribers: sanjoy, mzolotukhin, nemanjai, llvm-commits Differential Revision: https://reviews.llvm.org/D23483 llvm-svn: 278591 --- llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp | 160 +++++++++++++++--------- 1 file changed, 100 insertions(+), 60 deletions(-) (limited to 'llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp') diff --git a/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp b/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp index 0b0e794d832..ed58acac078 100644 --- a/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopDataPrefetch.cpp @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar/LoopDataPrefetch.h" + #define DEBUG_TYPE "loop-data-prefetch" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/Statistic.h" @@ -59,80 +61,89 @@ static cl::opt MaxPrefetchIterationsAhead( STATISTIC(NumPrefetches, "Number of prefetches inserted"); -namespace llvm { - void initializeLoopDataPrefetchPass(PassRegistry&); -} - namespace { - class LoopDataPrefetch : public FunctionPass { - public: - static char ID; // Pass ID, replacement for typeid - LoopDataPrefetch() : FunctionPass(ID) { - initializeLoopDataPrefetchPass(*PassRegistry::getPassRegistry()); - } +/// Loop prefetch implementation class. +class LoopDataPrefetch { +public: + LoopDataPrefetch(AssumptionCache *AC, LoopInfo *LI, ScalarEvolution *SE, + const TargetTransformInfo *TTI, + OptimizationRemarkEmitter *ORE) + : AC(AC), LI(LI), SE(SE), TTI(TTI), ORE(ORE) {} - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - AU.addPreserved(); - AU.addRequired(); - AU.addPreserved(); - AU.addRequired(); - AU.addRequired(); - // FIXME: For some reason, preserving SE here breaks LSR (even if - // this pass changes nothing). - // AU.addPreserved(); - AU.addRequired(); - } + bool run(); - bool runOnFunction(Function &F) override; +private: + bool runOnLoop(Loop *L); - private: - bool runOnLoop(Loop *L); + /// \brief Check if the the stride of the accesses is large enough to + /// warrant a prefetch. + bool isStrideLargeEnough(const SCEVAddRecExpr *AR); - /// \brief Check if the the stride of the accesses is large enough to - /// warrant a prefetch. - bool isStrideLargeEnough(const SCEVAddRecExpr *AR); + unsigned getMinPrefetchStride() { + if (MinPrefetchStride.getNumOccurrences() > 0) + return MinPrefetchStride; + return TTI->getMinPrefetchStride(); + } - unsigned getMinPrefetchStride() { - if (MinPrefetchStride.getNumOccurrences() > 0) - return MinPrefetchStride; - return TTI->getMinPrefetchStride(); - } + unsigned getPrefetchDistance() { + if (PrefetchDistance.getNumOccurrences() > 0) + return PrefetchDistance; + return TTI->getPrefetchDistance(); + } - unsigned getPrefetchDistance() { - if (PrefetchDistance.getNumOccurrences() > 0) - return PrefetchDistance; - return TTI->getPrefetchDistance(); - } + unsigned getMaxPrefetchIterationsAhead() { + if (MaxPrefetchIterationsAhead.getNumOccurrences() > 0) + return MaxPrefetchIterationsAhead; + return TTI->getMaxPrefetchIterationsAhead(); + } - unsigned getMaxPrefetchIterationsAhead() { - if (MaxPrefetchIterationsAhead.getNumOccurrences() > 0) - return MaxPrefetchIterationsAhead; - return TTI->getMaxPrefetchIterationsAhead(); - } + AssumptionCache *AC; + LoopInfo *LI; + ScalarEvolution *SE; + const TargetTransformInfo *TTI; + OptimizationRemarkEmitter *ORE; +}; + +/// Legacy class for inserting loop data prefetches. +class LoopDataPrefetchLegacyPass : public FunctionPass { +public: + static char ID; // Pass ID, replacement for typeid + LoopDataPrefetchLegacyPass() : FunctionPass(ID) { + initializeLoopDataPrefetchLegacyPassPass(*PassRegistry::getPassRegistry()); + } - AssumptionCache *AC; - LoopInfo *LI; - ScalarEvolution *SE; - const TargetTransformInfo *TTI; - const DataLayout *DL; - OptimizationRemarkEmitter *ORE; + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + AU.addRequired(); + AU.addRequired(); + // FIXME: For some reason, preserving SE here breaks LSR (even if + // this pass changes nothing). + // AU.addPreserved(); + AU.addRequired(); + } + + bool runOnFunction(Function &F) override; }; } -char LoopDataPrefetch::ID = 0; -INITIALIZE_PASS_BEGIN(LoopDataPrefetch, "loop-data-prefetch", +char LoopDataPrefetchLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(LoopDataPrefetchLegacyPass, "loop-data-prefetch", "Loop Data Prefetch", false, false) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) -INITIALIZE_PASS_END(LoopDataPrefetch, "loop-data-prefetch", +INITIALIZE_PASS_END(LoopDataPrefetchLegacyPass, "loop-data-prefetch", "Loop Data Prefetch", false, false) -FunctionPass *llvm::createLoopDataPrefetchPass() { return new LoopDataPrefetch(); } +FunctionPass *llvm::createLoopDataPrefetchPass() { + return new LoopDataPrefetchLegacyPass(); +} bool LoopDataPrefetch::isStrideLargeEnough(const SCEVAddRecExpr *AR) { unsigned TargetMinStride = getMinPrefetchStride(); @@ -150,17 +161,46 @@ bool LoopDataPrefetch::isStrideLargeEnough(const SCEVAddRecExpr *AR) { return TargetMinStride <= AbsStride; } -bool LoopDataPrefetch::runOnFunction(Function &F) { +PreservedAnalyses LoopDataPrefetchPass::run(Function &F, + FunctionAnalysisManager &AM) { + LoopInfo *LI = &AM.getResult(F); + ScalarEvolution *SE = &AM.getResult(F); + AssumptionCache *AC = &AM.getResult(F); + OptimizationRemarkEmitter *ORE = + &AM.getResult(F); + const TargetTransformInfo *TTI = &AM.getResult(F); + + LoopDataPrefetch LDP(AC, LI, SE, TTI, ORE); + bool Changed = LDP.run(); + + if (Changed) { + PreservedAnalyses PA; + PA.preserve(); + PA.preserve(); + return PA; + } + + return PreservedAnalyses::all(); +} + +bool LoopDataPrefetchLegacyPass::runOnFunction(Function &F) { if (skipFunction(F)) return false; - LI = &getAnalysis().getLoopInfo(); - SE = &getAnalysis().getSE(); - DL = &F.getParent()->getDataLayout(); - AC = &getAnalysis().getAssumptionCache(F); - ORE = &getAnalysis().getORE(); - TTI = &getAnalysis().getTTI(F); + LoopInfo *LI = &getAnalysis().getLoopInfo(); + ScalarEvolution *SE = &getAnalysis().getSE(); + AssumptionCache *AC = + &getAnalysis().getAssumptionCache(F); + OptimizationRemarkEmitter *ORE = + &getAnalysis().getORE(); + const TargetTransformInfo *TTI = + &getAnalysis().getTTI(F); + + LoopDataPrefetch LDP(AC, LI, SE, TTI, ORE); + return LDP.run(); +} +bool LoopDataPrefetch::run() { // If PrefetchDistance is not set, don't run the pass. This gives an // opportunity for targets to run this pass for selected subtargets only // (whose TTI sets PrefetchDistance). -- cgit v1.2.3