blob: 1fcf1315a1777a1c2aad345a4bd660e9f3700913 [file] [log] [blame]
Adam Nemet9d9cb272016-02-18 21:38:19 +00001//===-------- LoopDataPrefetch.cpp - Loop Data Prefetching Pass -----------===//
Hal Finkele5aaf3f2015-02-20 05:08:21 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Hal Finkele5aaf3f2015-02-20 05:08:21 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements a Loop Data Prefetching Pass.
10//
11//===----------------------------------------------------------------------===//
12
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000013#include "llvm/Transforms/Scalar/LoopDataPrefetch.h"
14
Adam Nemet7cf9b1b2016-02-18 21:37:12 +000015#define DEBUG_TYPE "loop-data-prefetch"
Hal Finkela9fceb82015-04-10 15:05:02 +000016#include "llvm/ADT/DepthFirstIterator.h"
Hal Finkele5aaf3f2015-02-20 05:08:21 +000017#include "llvm/ADT/Statistic.h"
Daniel Jasperaec2fa32016-12-19 08:22:17 +000018#include "llvm/Analysis/AssumptionCache.h"
Hal Finkele5aaf3f2015-02-20 05:08:21 +000019#include "llvm/Analysis/CodeMetrics.h"
Hal Finkele5aaf3f2015-02-20 05:08:21 +000020#include "llvm/Analysis/LoopInfo.h"
Adam Nemet0965da22017-10-09 23:19:02 +000021#include "llvm/Analysis/OptimizationRemarkEmitter.h"
Hal Finkele5aaf3f2015-02-20 05:08:21 +000022#include "llvm/Analysis/ScalarEvolution.h"
23#include "llvm/Analysis/ScalarEvolutionExpander.h"
24#include "llvm/Analysis/ScalarEvolutionExpressions.h"
25#include "llvm/Analysis/TargetTransformInfo.h"
Hal Finkele5aaf3f2015-02-20 05:08:21 +000026#include "llvm/IR/CFG.h"
27#include "llvm/IR/Dominators.h"
28#include "llvm/IR/Function.h"
Hal Finkele5aaf3f2015-02-20 05:08:21 +000029#include "llvm/IR/Module.h"
30#include "llvm/Support/CommandLine.h"
31#include "llvm/Support/Debug.h"
Adam Nemet885f1de2016-07-22 22:53:12 +000032#include "llvm/Transforms/Scalar.h"
Hal Finkele5aaf3f2015-02-20 05:08:21 +000033#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Hal Finkele5aaf3f2015-02-20 05:08:21 +000034#include "llvm/Transforms/Utils/ValueMapper.h"
35using namespace llvm;
36
37// By default, we limit this to creating 16 PHIs (which is a little over half
38// of the allocatable register set).
39static cl::opt<bool>
Adam Nemet7cf9b1b2016-02-18 21:37:12 +000040PrefetchWrites("loop-prefetch-writes", cl::Hidden, cl::init(false),
Hal Finkele5aaf3f2015-02-20 05:08:21 +000041 cl::desc("Prefetch write addresses"));
42
Adam Nemet1428d412016-03-29 23:45:52 +000043static cl::opt<unsigned>
44 PrefetchDistance("prefetch-distance",
45 cl::desc("Number of instructions to prefetch ahead"),
46 cl::Hidden);
47
48static cl::opt<unsigned>
49 MinPrefetchStride("min-prefetch-stride",
50 cl::desc("Min stride to add prefetches"), cl::Hidden);
51
52static cl::opt<unsigned> MaxPrefetchIterationsAhead(
53 "max-prefetch-iters-ahead",
54 cl::desc("Max number of iterations to prefetch ahead"), cl::Hidden);
55
Adam Nemet34785ec2016-03-09 05:33:21 +000056STATISTIC(NumPrefetches, "Number of prefetches inserted");
57
Hal Finkele5aaf3f2015-02-20 05:08:21 +000058namespace {
59
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000060/// Loop prefetch implementation class.
61class LoopDataPrefetch {
62public:
Daniel Jasperaec2fa32016-12-19 08:22:17 +000063 LoopDataPrefetch(AssumptionCache *AC, LoopInfo *LI, ScalarEvolution *SE,
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000064 const TargetTransformInfo *TTI,
65 OptimizationRemarkEmitter *ORE)
Daniel Jasperaec2fa32016-12-19 08:22:17 +000066 : AC(AC), LI(LI), SE(SE), TTI(TTI), ORE(ORE) {}
Hal Finkele5aaf3f2015-02-20 05:08:21 +000067
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000068 bool run();
Hal Finkele5aaf3f2015-02-20 05:08:21 +000069
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000070private:
71 bool runOnLoop(Loop *L);
Adam Nemet85fba392016-03-29 22:40:02 +000072
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000073 /// Check if the stride of the accesses is large enough to
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000074 /// warrant a prefetch.
75 bool isStrideLargeEnough(const SCEVAddRecExpr *AR);
Hal Finkele5aaf3f2015-02-20 05:08:21 +000076
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000077 unsigned getMinPrefetchStride() {
78 if (MinPrefetchStride.getNumOccurrences() > 0)
79 return MinPrefetchStride;
80 return TTI->getMinPrefetchStride();
81 }
Adam Nemet6d8beec2016-03-18 00:27:38 +000082
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000083 unsigned getPrefetchDistance() {
84 if (PrefetchDistance.getNumOccurrences() > 0)
85 return PrefetchDistance;
86 return TTI->getPrefetchDistance();
87 }
Adam Nemet1428d412016-03-29 23:45:52 +000088
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000089 unsigned getMaxPrefetchIterationsAhead() {
90 if (MaxPrefetchIterationsAhead.getNumOccurrences() > 0)
91 return MaxPrefetchIterationsAhead;
92 return TTI->getMaxPrefetchIterationsAhead();
93 }
Adam Nemet1428d412016-03-29 23:45:52 +000094
Daniel Jasperaec2fa32016-12-19 08:22:17 +000095 AssumptionCache *AC;
Teresa Johnson1eca6bc2016-08-13 04:11:27 +000096 LoopInfo *LI;
97 ScalarEvolution *SE;
98 const TargetTransformInfo *TTI;
99 OptimizationRemarkEmitter *ORE;
100};
Adam Nemet1428d412016-03-29 23:45:52 +0000101
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000102/// Legacy class for inserting loop data prefetches.
103class LoopDataPrefetchLegacyPass : public FunctionPass {
104public:
105 static char ID; // Pass ID, replacement for typeid
106 LoopDataPrefetchLegacyPass() : FunctionPass(ID) {
107 initializeLoopDataPrefetchLegacyPassPass(*PassRegistry::getPassRegistry());
108 }
109
110 void getAnalysisUsage(AnalysisUsage &AU) const override {
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000111 AU.addRequired<AssumptionCacheTracker>();
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000112 AU.addPreserved<DominatorTreeWrapperPass>();
113 AU.addRequired<LoopInfoWrapperPass>();
114 AU.addPreserved<LoopInfoWrapperPass>();
115 AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
116 AU.addRequired<ScalarEvolutionWrapperPass>();
Geoff Berry40549ad2017-08-16 19:03:16 +0000117 AU.addPreserved<ScalarEvolutionWrapperPass>();
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000118 AU.addRequired<TargetTransformInfoWrapperPass>();
119 }
120
121 bool runOnFunction(Function &F) override;
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000122 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000123}
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000124
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000125char LoopDataPrefetchLegacyPass::ID = 0;
126INITIALIZE_PASS_BEGIN(LoopDataPrefetchLegacyPass, "loop-data-prefetch",
Adam Nemet7cf9b1b2016-02-18 21:37:12 +0000127 "Loop Data Prefetch", false, false)
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000128INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000129INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
130INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
Adam Nemet9e6e63f2016-07-22 22:53:17 +0000131INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
Chandler Carruth2f1fd162015-08-17 02:08:17 +0000132INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000133INITIALIZE_PASS_END(LoopDataPrefetchLegacyPass, "loop-data-prefetch",
Adam Nemet7cf9b1b2016-02-18 21:37:12 +0000134 "Loop Data Prefetch", false, false)
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000135
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000136FunctionPass *llvm::createLoopDataPrefetchPass() {
137 return new LoopDataPrefetchLegacyPass();
138}
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000139
Adam Nemet6d8beec2016-03-18 00:27:38 +0000140bool LoopDataPrefetch::isStrideLargeEnough(const SCEVAddRecExpr *AR) {
Adam Nemet1428d412016-03-29 23:45:52 +0000141 unsigned TargetMinStride = getMinPrefetchStride();
Adam Nemet6d8beec2016-03-18 00:27:38 +0000142 // No need to check if any stride goes.
143 if (TargetMinStride <= 1)
144 return true;
145
146 const auto *ConstStride = dyn_cast<SCEVConstant>(AR->getStepRecurrence(*SE));
147 // If MinStride is set, don't prefetch unless we can ensure that stride is
148 // larger.
149 if (!ConstStride)
150 return false;
151
152 unsigned AbsStride = std::abs(ConstStride->getAPInt().getSExtValue());
153 return TargetMinStride <= AbsStride;
154}
155
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000156PreservedAnalyses LoopDataPrefetchPass::run(Function &F,
157 FunctionAnalysisManager &AM) {
158 LoopInfo *LI = &AM.getResult<LoopAnalysis>(F);
159 ScalarEvolution *SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000160 AssumptionCache *AC = &AM.getResult<AssumptionAnalysis>(F);
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000161 OptimizationRemarkEmitter *ORE =
162 &AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
163 const TargetTransformInfo *TTI = &AM.getResult<TargetIRAnalysis>(F);
164
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000165 LoopDataPrefetch LDP(AC, LI, SE, TTI, ORE);
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000166 bool Changed = LDP.run();
167
168 if (Changed) {
169 PreservedAnalyses PA;
170 PA.preserve<DominatorTreeAnalysis>();
171 PA.preserve<LoopAnalysis>();
172 return PA;
173 }
174
175 return PreservedAnalyses::all();
176}
177
178bool LoopDataPrefetchLegacyPass::runOnFunction(Function &F) {
Andrew Kaylor50271f72016-05-03 22:32:30 +0000179 if (skipFunction(F))
180 return false;
181
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000182 LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
183 ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000184 AssumptionCache *AC =
185 &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000186 OptimizationRemarkEmitter *ORE =
187 &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
188 const TargetTransformInfo *TTI =
189 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000190
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000191 LoopDataPrefetch LDP(AC, LI, SE, TTI, ORE);
Teresa Johnson1eca6bc2016-08-13 04:11:27 +0000192 return LDP.run();
193}
194
195bool LoopDataPrefetch::run() {
Adam Nemetbb3680b2016-03-07 18:35:42 +0000196 // If PrefetchDistance is not set, don't run the pass. This gives an
197 // opportunity for targets to run this pass for selected subtargets only
198 // (whose TTI sets PrefetchDistance).
Adam Nemet1428d412016-03-29 23:45:52 +0000199 if (getPrefetchDistance() == 0)
Adam Nemetbb3680b2016-03-07 18:35:42 +0000200 return false;
Adam Nemetaf761102016-01-21 18:28:36 +0000201 assert(TTI->getCacheLineSize() && "Cache line size is not set for target");
202
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000203 bool MadeChange = false;
204
Benjamin Kramer135f7352016-06-26 12:28:59 +0000205 for (Loop *I : *LI)
206 for (auto L = df_begin(I), LE = df_end(I); L != LE; ++L)
Hal Finkel5551f252015-04-12 17:18:56 +0000207 MadeChange |= runOnLoop(*L);
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000208
209 return MadeChange;
210}
211
Adam Nemet7cf9b1b2016-02-18 21:37:12 +0000212bool LoopDataPrefetch::runOnLoop(Loop *L) {
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000213 bool MadeChange = false;
214
215 // Only prefetch in the inner-most loop
216 if (!L->empty())
217 return MadeChange;
218
219 SmallPtrSet<const Value *, 32> EphValues;
Daniel Jasperaec2fa32016-12-19 08:22:17 +0000220 CodeMetrics::collectEphemeralValues(L, AC, EphValues);
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000221
222 // Calculate the number of iterations ahead to prefetch
223 CodeMetrics Metrics;
Balaram Makamc6cebf72016-09-08 17:08:20 +0000224 for (const auto BB : L->blocks()) {
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000225 // If the loop already has prefetches, then assume that the user knows
Nico Weber2cf5e892016-06-10 20:06:03 +0000226 // what they are doing and don't add any more.
Balaram Makamc6cebf72016-09-08 17:08:20 +0000227 for (auto &I : *BB)
228 if (CallInst *CI = dyn_cast<CallInst>(&I))
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000229 if (Function *F = CI->getCalledFunction())
230 if (F->getIntrinsicID() == Intrinsic::prefetch)
231 return MadeChange;
232
Balaram Makamc6cebf72016-09-08 17:08:20 +0000233 Metrics.analyzeBasicBlock(BB, *TTI, EphValues);
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000234 }
235 unsigned LoopSize = Metrics.NumInsts;
236 if (!LoopSize)
237 LoopSize = 1;
238
Adam Nemet1428d412016-03-29 23:45:52 +0000239 unsigned ItersAhead = getPrefetchDistance() / LoopSize;
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000240 if (!ItersAhead)
241 ItersAhead = 1;
242
Adam Nemet1428d412016-03-29 23:45:52 +0000243 if (ItersAhead > getMaxPrefetchIterationsAhead())
Adam Nemet709e3042016-03-18 00:27:43 +0000244 return MadeChange;
245
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000246 LLVM_DEBUG(dbgs() << "Prefetching " << ItersAhead
247 << " iterations ahead (loop size: " << LoopSize << ") in "
248 << L->getHeader()->getParent()->getName() << ": " << *L);
Adam Nemet34785ec2016-03-09 05:33:21 +0000249
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000250 SmallVector<std::pair<Instruction *, const SCEVAddRecExpr *>, 16> PrefLoads;
Balaram Makamc6cebf72016-09-08 17:08:20 +0000251 for (const auto BB : L->blocks()) {
252 for (auto &I : *BB) {
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000253 Value *PtrValue;
254 Instruction *MemI;
255
Balaram Makamc6cebf72016-09-08 17:08:20 +0000256 if (LoadInst *LMemI = dyn_cast<LoadInst>(&I)) {
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000257 MemI = LMemI;
258 PtrValue = LMemI->getPointerOperand();
Balaram Makamc6cebf72016-09-08 17:08:20 +0000259 } else if (StoreInst *SMemI = dyn_cast<StoreInst>(&I)) {
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000260 if (!PrefetchWrites) continue;
261 MemI = SMemI;
262 PtrValue = SMemI->getPointerOperand();
263 } else continue;
264
265 unsigned PtrAddrSpace = PtrValue->getType()->getPointerAddressSpace();
266 if (PtrAddrSpace)
267 continue;
268
269 if (L->isLoopInvariant(PtrValue))
270 continue;
271
272 const SCEV *LSCEV = SE->getSCEV(PtrValue);
273 const SCEVAddRecExpr *LSCEVAddRec = dyn_cast<SCEVAddRecExpr>(LSCEV);
274 if (!LSCEVAddRec)
275 continue;
276
Hiroshi Inoued24ddcd2018-01-19 10:55:29 +0000277 // Check if the stride of the accesses is large enough to warrant a
Adam Nemet6d8beec2016-03-18 00:27:38 +0000278 // prefetch.
279 if (!isStrideLargeEnough(LSCEVAddRec))
280 continue;
281
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000282 // We don't want to double prefetch individual cache lines. If this load
283 // is known to be within one cache line of some other load that has
284 // already been prefetched, then don't prefetch this one as well.
285 bool DupPref = false;
Benjamin Kramer135f7352016-06-26 12:28:59 +0000286 for (const auto &PrefLoad : PrefLoads) {
287 const SCEV *PtrDiff = SE->getMinusSCEV(LSCEVAddRec, PrefLoad.second);
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000288 if (const SCEVConstant *ConstPtrDiff =
289 dyn_cast<SCEVConstant>(PtrDiff)) {
Benjamin Kramer7bd1f7c2015-03-09 20:20:16 +0000290 int64_t PD = std::abs(ConstPtrDiff->getValue()->getSExtValue());
Adam Nemetaf761102016-01-21 18:28:36 +0000291 if (PD < (int64_t) TTI->getCacheLineSize()) {
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000292 DupPref = true;
293 break;
294 }
295 }
296 }
297 if (DupPref)
298 continue;
299
300 const SCEV *NextLSCEV = SE->getAddExpr(LSCEVAddRec, SE->getMulExpr(
301 SE->getConstant(LSCEVAddRec->getType(), ItersAhead),
302 LSCEVAddRec->getStepRecurrence(*SE)));
303 if (!isSafeToExpand(NextLSCEV, *SE))
304 continue;
305
306 PrefLoads.push_back(std::make_pair(MemI, LSCEVAddRec));
307
Balaram Makamc6cebf72016-09-08 17:08:20 +0000308 Type *I8Ptr = Type::getInt8PtrTy(BB->getContext(), PtrAddrSpace);
309 SCEVExpander SCEVE(*SE, I.getModule()->getDataLayout(), "prefaddr");
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000310 Value *PrefPtrValue = SCEVE.expandCodeFor(NextLSCEV, I8Ptr, MemI);
311
312 IRBuilder<> Builder(MemI);
Balaram Makamc6cebf72016-09-08 17:08:20 +0000313 Module *M = BB->getParent()->getParent();
314 Type *I32 = Type::getInt32Ty(BB->getContext());
James Y Knight7976eb52019-02-01 20:43:25 +0000315 Function *PrefetchFunc =
316 Intrinsic::getDeclaration(M, Intrinsic::prefetch);
David Blaikieff6409d2015-05-18 22:13:54 +0000317 Builder.CreateCall(
318 PrefetchFunc,
319 {PrefPtrValue,
320 ConstantInt::get(I32, MemI->mayReadFromMemory() ? 0 : 1),
321 ConstantInt::get(I32, 3), ConstantInt::get(I32, 1)});
Adam Nemet34785ec2016-03-09 05:33:21 +0000322 ++NumPrefetches;
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000323 LLVM_DEBUG(dbgs() << " Access: " << *PtrValue << ", SCEV: " << *LSCEV
324 << "\n");
Vivek Pandya95906582017-10-11 17:12:59 +0000325 ORE->emit([&]() {
326 return OptimizationRemark(DEBUG_TYPE, "Prefetched", MemI)
327 << "prefetched memory access";
328 });
Hal Finkele5aaf3f2015-02-20 05:08:21 +0000329
330 MadeChange = true;
331 }
332 }
333
334 return MadeChange;
335}