blob: bdea338f21d04a39864cfdca13c1c3a699b891eb [file] [log] [blame]
Andrew Trick9e764222011-06-04 01:16:30 +00001//===-- BranchProbabilityInfo.cpp - Branch Probability Analysis -*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Loops should be simplified before this analysis.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Instructions.h"
15#include "llvm/Analysis/BranchProbabilityInfo.h"
Jakub Staszak12af93a2011-07-16 20:31:15 +000016#include "llvm/Analysis/LoopInfo.h"
Andrew Trickf289df22011-06-11 01:05:22 +000017#include "llvm/Support/Debug.h"
Andrew Trick9e764222011-06-04 01:16:30 +000018
19using namespace llvm;
20
21INITIALIZE_PASS_BEGIN(BranchProbabilityInfo, "branch-prob",
22 "Branch Probability Analysis", false, true)
23INITIALIZE_PASS_DEPENDENCY(LoopInfo)
24INITIALIZE_PASS_END(BranchProbabilityInfo, "branch-prob",
25 "Branch Probability Analysis", false, true)
26
27char BranchProbabilityInfo::ID = 0;
28
Benjamin Kramerafa88ea2011-06-13 18:38:56 +000029namespace {
Andrew Trick9e764222011-06-04 01:16:30 +000030// Please note that BranchProbabilityAnalysis is not a FunctionPass.
31// It is created by BranchProbabilityInfo (which is a FunctionPass), which
32// provides a clear interface. Thanks to that, all heuristics and other
33// private methods are hidden in the .cpp file.
34class BranchProbabilityAnalysis {
35
36 typedef std::pair<BasicBlock *, BasicBlock *> Edge;
37
Andrew Trickf289df22011-06-11 01:05:22 +000038 DenseMap<Edge, uint32_t> *Weights;
Andrew Trick9e764222011-06-04 01:16:30 +000039
40 BranchProbabilityInfo *BP;
41
42 LoopInfo *LI;
43
44
45 // Weights are for internal use only. They are used by heuristics to help to
46 // estimate edges' probability. Example:
47 //
48 // Using "Loop Branch Heuristics" we predict weights of edges for the
49 // block BB2.
50 // ...
51 // |
52 // V
53 // BB1<-+
54 // | |
Jakub Staszak3d8b15e2011-07-28 23:42:08 +000055 // | | (Weight = 124)
Andrew Trick9e764222011-06-04 01:16:30 +000056 // V |
57 // BB2--+
58 // |
59 // | (Weight = 4)
60 // V
61 // BB3
62 //
Jakub Staszak3d8b15e2011-07-28 23:42:08 +000063 // Probability of the edge BB2->BB1 = 124 / (124 + 4) = 0.96875
64 // Probability of the edge BB2->BB3 = 4 / (124 + 4) = 0.03125
Andrew Trick9e764222011-06-04 01:16:30 +000065
Jakub Staszak3d8b15e2011-07-28 23:42:08 +000066 static const uint32_t LBH_TAKEN_WEIGHT = 124;
Andrew Trickf289df22011-06-11 01:05:22 +000067 static const uint32_t LBH_NONTAKEN_WEIGHT = 4;
Andrew Trick9e764222011-06-04 01:16:30 +000068
Jakub Staszake0058b42011-07-29 02:36:53 +000069 static const uint32_t RH_TAKEN_WEIGHT = 24;
70 static const uint32_t RH_NONTAKEN_WEIGHT = 8;
71
72 static const uint32_t PH_TAKEN_WEIGHT = 20;
73 static const uint32_t PH_NONTAKEN_WEIGHT = 12;
74
Andrew Trick9e764222011-06-04 01:16:30 +000075 // Standard weight value. Used when none of the heuristics set weight for
76 // the edge.
Andrew Trickf289df22011-06-11 01:05:22 +000077 static const uint32_t NORMAL_WEIGHT = 16;
Andrew Trick9e764222011-06-04 01:16:30 +000078
79 // Minimum weight of an edge. Please note, that weight is NEVER 0.
Andrew Trickf289df22011-06-11 01:05:22 +000080 static const uint32_t MIN_WEIGHT = 1;
Andrew Trick9e764222011-06-04 01:16:30 +000081
82 // Return TRUE if BB leads directly to a Return Instruction.
83 static bool isReturningBlock(BasicBlock *BB) {
84 SmallPtrSet<BasicBlock *, 8> Visited;
85
86 while (true) {
87 TerminatorInst *TI = BB->getTerminator();
88 if (isa<ReturnInst>(TI))
89 return true;
90
91 if (TI->getNumSuccessors() > 1)
92 break;
93
94 // It is unreachable block which we can consider as a return instruction.
95 if (TI->getNumSuccessors() == 0)
96 return true;
97
98 Visited.insert(BB);
99 BB = TI->getSuccessor(0);
100
101 // Stop if cycle is detected.
102 if (Visited.count(BB))
103 return false;
104 }
105
106 return false;
107 }
108
Andrew Trickf289df22011-06-11 01:05:22 +0000109 uint32_t getMaxWeightFor(BasicBlock *BB) const {
110 return UINT32_MAX / BB->getTerminator()->getNumSuccessors();
Andrew Trick9e764222011-06-04 01:16:30 +0000111 }
112
113public:
Andrew Trickf289df22011-06-11 01:05:22 +0000114 BranchProbabilityAnalysis(DenseMap<Edge, uint32_t> *W,
Andrew Trick9e764222011-06-04 01:16:30 +0000115 BranchProbabilityInfo *BP, LoopInfo *LI)
116 : Weights(W), BP(BP), LI(LI) {
117 }
118
119 // Return Heuristics
Jakub Staszak7241caf2011-07-28 21:45:07 +0000120 bool calcReturnHeuristics(BasicBlock *BB);
Andrew Trick9e764222011-06-04 01:16:30 +0000121
122 // Pointer Heuristics
Jakub Staszak7241caf2011-07-28 21:45:07 +0000123 bool calcPointerHeuristics(BasicBlock *BB);
Andrew Trick9e764222011-06-04 01:16:30 +0000124
125 // Loop Branch Heuristics
Jakub Staszak7241caf2011-07-28 21:45:07 +0000126 bool calcLoopBranchHeuristics(BasicBlock *BB);
Andrew Trick9e764222011-06-04 01:16:30 +0000127
128 bool runOnFunction(Function &F);
129};
Benjamin Kramerafa88ea2011-06-13 18:38:56 +0000130} // end anonymous namespace
Andrew Trick9e764222011-06-04 01:16:30 +0000131
132// Calculate Edge Weights using "Return Heuristics". Predict a successor which
133// leads directly to Return Instruction will not be taken.
Jakub Staszak7241caf2011-07-28 21:45:07 +0000134bool BranchProbabilityAnalysis::calcReturnHeuristics(BasicBlock *BB){
Andrew Trick9e764222011-06-04 01:16:30 +0000135 if (BB->getTerminator()->getNumSuccessors() == 1)
Jakub Staszak7241caf2011-07-28 21:45:07 +0000136 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000137
Jakub Staszake0058b42011-07-29 02:36:53 +0000138 SmallVector<BasicBlock *, 4> ReturningEdges;
139 SmallVector<BasicBlock *, 4> StayEdges;
140
Andrew Trick9e764222011-06-04 01:16:30 +0000141 for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
142 BasicBlock *Succ = *I;
Jakub Staszake0058b42011-07-29 02:36:53 +0000143 if (isReturningBlock(Succ))
144 ReturningEdges.push_back(Succ);
145 else
146 StayEdges.push_back(Succ);
147 }
148
149 if (uint32_t numStayEdges = StayEdges.size()) {
150 uint32_t stayWeight = RH_TAKEN_WEIGHT / numStayEdges;
151 if (stayWeight < NORMAL_WEIGHT)
152 stayWeight = NORMAL_WEIGHT;
153
154 for (SmallVector<BasicBlock *, 4>::iterator I = StayEdges.begin(),
155 E = StayEdges.end(); I != E; ++I)
156 BP->setEdgeWeight(BB, *I, stayWeight);
157 }
158
159 if (uint32_t numRetEdges = ReturningEdges.size()) {
160 uint32_t retWeight = RH_NONTAKEN_WEIGHT / numRetEdges;
161 if (retWeight < MIN_WEIGHT)
162 retWeight = MIN_WEIGHT;
163 for (SmallVector<BasicBlock *, 4>::iterator I = ReturningEdges.begin(),
164 E = ReturningEdges.end(); I != E; ++I) {
165 BP->setEdgeWeight(BB, *I, retWeight);
Andrew Trick9e764222011-06-04 01:16:30 +0000166 }
167 }
Jakub Staszak7241caf2011-07-28 21:45:07 +0000168
Jakub Staszake0058b42011-07-29 02:36:53 +0000169 return ReturningEdges.size() > 0;
Andrew Trick9e764222011-06-04 01:16:30 +0000170}
171
172// Calculate Edge Weights using "Pointer Heuristics". Predict a comparsion
173// between two pointer or pointer and NULL will fail.
Jakub Staszak7241caf2011-07-28 21:45:07 +0000174bool BranchProbabilityAnalysis::calcPointerHeuristics(BasicBlock *BB) {
Andrew Trick9e764222011-06-04 01:16:30 +0000175 BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator());
176 if (!BI || !BI->isConditional())
Jakub Staszak7241caf2011-07-28 21:45:07 +0000177 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000178
179 Value *Cond = BI->getCondition();
180 ICmpInst *CI = dyn_cast<ICmpInst>(Cond);
Jakub Staszakd7932ca2011-07-15 20:51:06 +0000181 if (!CI || !CI->isEquality())
Jakub Staszak7241caf2011-07-28 21:45:07 +0000182 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000183
184 Value *LHS = CI->getOperand(0);
Andrew Trick9e764222011-06-04 01:16:30 +0000185
186 if (!LHS->getType()->isPointerTy())
Jakub Staszak7241caf2011-07-28 21:45:07 +0000187 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000188
Nick Lewycky404b53e2011-06-04 02:07:10 +0000189 assert(CI->getOperand(1)->getType()->isPointerTy());
Andrew Trick9e764222011-06-04 01:16:30 +0000190
191 BasicBlock *Taken = BI->getSuccessor(0);
192 BasicBlock *NonTaken = BI->getSuccessor(1);
193
194 // p != 0 -> isProb = true
195 // p == 0 -> isProb = false
196 // p != q -> isProb = true
197 // p == q -> isProb = false;
Jakub Staszakd7932ca2011-07-15 20:51:06 +0000198 bool isProb = CI->getPredicate() == ICmpInst::ICMP_NE;
Andrew Trick9e764222011-06-04 01:16:30 +0000199 if (!isProb)
200 std::swap(Taken, NonTaken);
201
Jakub Staszake0058b42011-07-29 02:36:53 +0000202 BP->setEdgeWeight(BB, Taken, PH_TAKEN_WEIGHT);
203 BP->setEdgeWeight(BB, NonTaken, PH_NONTAKEN_WEIGHT);
Jakub Staszak7241caf2011-07-28 21:45:07 +0000204 return true;
Andrew Trick9e764222011-06-04 01:16:30 +0000205}
206
207// Calculate Edge Weights using "Loop Branch Heuristics". Predict backedges
208// as taken, exiting edges as not-taken.
Jakub Staszak7241caf2011-07-28 21:45:07 +0000209bool BranchProbabilityAnalysis::calcLoopBranchHeuristics(BasicBlock *BB) {
Andrew Trickf289df22011-06-11 01:05:22 +0000210 uint32_t numSuccs = BB->getTerminator()->getNumSuccessors();
Andrew Trick9e764222011-06-04 01:16:30 +0000211
212 Loop *L = LI->getLoopFor(BB);
213 if (!L)
Jakub Staszak7241caf2011-07-28 21:45:07 +0000214 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000215
216 SmallVector<BasicBlock *, 8> BackEdges;
217 SmallVector<BasicBlock *, 8> ExitingEdges;
Jakub Staszakfa447252011-07-28 21:33:46 +0000218 SmallVector<BasicBlock *, 8> InEdges; // Edges from header to the loop.
219
220 bool isHeader = BB == L->getHeader();
Andrew Trick9e764222011-06-04 01:16:30 +0000221
222 for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
223 BasicBlock *Succ = *I;
224 Loop *SuccL = LI->getLoopFor(Succ);
225 if (SuccL != L)
226 ExitingEdges.push_back(Succ);
227 else if (Succ == L->getHeader())
228 BackEdges.push_back(Succ);
Jakub Staszakfa447252011-07-28 21:33:46 +0000229 else if (isHeader)
230 InEdges.push_back(Succ);
Andrew Trick9e764222011-06-04 01:16:30 +0000231 }
232
Andrew Trickf289df22011-06-11 01:05:22 +0000233 if (uint32_t numBackEdges = BackEdges.size()) {
234 uint32_t backWeight = LBH_TAKEN_WEIGHT / numBackEdges;
Andrew Trick9e764222011-06-04 01:16:30 +0000235 if (backWeight < NORMAL_WEIGHT)
236 backWeight = NORMAL_WEIGHT;
237
238 for (SmallVector<BasicBlock *, 8>::iterator EI = BackEdges.begin(),
239 EE = BackEdges.end(); EI != EE; ++EI) {
240 BasicBlock *Back = *EI;
241 BP->setEdgeWeight(BB, Back, backWeight);
242 }
243 }
244
Jakub Staszakfa447252011-07-28 21:33:46 +0000245 if (uint32_t numInEdges = InEdges.size()) {
246 uint32_t inWeight = LBH_TAKEN_WEIGHT / numInEdges;
247 if (inWeight < NORMAL_WEIGHT)
248 inWeight = NORMAL_WEIGHT;
249
250 for (SmallVector<BasicBlock *, 8>::iterator EI = InEdges.begin(),
251 EE = InEdges.end(); EI != EE; ++EI) {
252 BasicBlock *Back = *EI;
253 BP->setEdgeWeight(BB, Back, inWeight);
254 }
255 }
256
Andrew Trickf289df22011-06-11 01:05:22 +0000257 uint32_t numExitingEdges = ExitingEdges.size();
258 if (uint32_t numNonExitingEdges = numSuccs - numExitingEdges) {
259 uint32_t exitWeight = LBH_NONTAKEN_WEIGHT / numNonExitingEdges;
Andrew Trick9e764222011-06-04 01:16:30 +0000260 if (exitWeight < MIN_WEIGHT)
261 exitWeight = MIN_WEIGHT;
262
263 for (SmallVector<BasicBlock *, 8>::iterator EI = ExitingEdges.begin(),
264 EE = ExitingEdges.end(); EI != EE; ++EI) {
265 BasicBlock *Exiting = *EI;
266 BP->setEdgeWeight(BB, Exiting, exitWeight);
267 }
268 }
Jakub Staszak7241caf2011-07-28 21:45:07 +0000269
270 return true;
Andrew Trick9e764222011-06-04 01:16:30 +0000271}
272
273bool BranchProbabilityAnalysis::runOnFunction(Function &F) {
274
275 for (Function::iterator I = F.begin(), E = F.end(); I != E; ) {
276 BasicBlock *BB = I++;
277
278 // Only LBH uses setEdgeWeight method.
Jakub Staszak7241caf2011-07-28 21:45:07 +0000279 if (calcLoopBranchHeuristics(BB))
280 continue;
Andrew Trick9e764222011-06-04 01:16:30 +0000281
282 // PH and RH use only incEdgeWeight and decEwdgeWeight methods to
283 // not efface LBH results.
Jakub Staszak7241caf2011-07-28 21:45:07 +0000284 if (calcReturnHeuristics(BB))
285 continue;
286
Andrew Trick9e764222011-06-04 01:16:30 +0000287 calcPointerHeuristics(BB);
Andrew Trick9e764222011-06-04 01:16:30 +0000288 }
289
290 return false;
291}
292
Jakub Staszak12af93a2011-07-16 20:31:15 +0000293void BranchProbabilityInfo::getAnalysisUsage(AnalysisUsage &AU) const {
294 AU.addRequired<LoopInfo>();
295 AU.setPreservesAll();
296}
Andrew Trick9e764222011-06-04 01:16:30 +0000297
298bool BranchProbabilityInfo::runOnFunction(Function &F) {
299 LoopInfo &LI = getAnalysis<LoopInfo>();
300 BranchProbabilityAnalysis BPA(&Weights, this, &LI);
Andrew Trickf289df22011-06-11 01:05:22 +0000301 return BPA.runOnFunction(F);
Andrew Trick9e764222011-06-04 01:16:30 +0000302}
303
Andrew Trickf289df22011-06-11 01:05:22 +0000304uint32_t BranchProbabilityInfo::getSumForBlock(BasicBlock *BB) const {
305 uint32_t Sum = 0;
306
307 for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
Andrew Trick9e764222011-06-04 01:16:30 +0000308 BasicBlock *Succ = *I;
Andrew Trickf289df22011-06-11 01:05:22 +0000309 uint32_t Weight = getEdgeWeight(BB, Succ);
310 uint32_t PrevSum = Sum;
Andrew Trick9e764222011-06-04 01:16:30 +0000311
312 Sum += Weight;
313 assert(Sum > PrevSum); (void) PrevSum;
314 }
315
Andrew Trickf289df22011-06-11 01:05:22 +0000316 return Sum;
317}
318
319bool BranchProbabilityInfo::isEdgeHot(BasicBlock *Src, BasicBlock *Dst) const {
320 // Hot probability is at least 4/5 = 80%
321 uint32_t Weight = getEdgeWeight(Src, Dst);
322 uint32_t Sum = getSumForBlock(Src);
323
324 // FIXME: Implement BranchProbability::compare then change this code to
325 // compare this BranchProbability against a static "hot" BranchProbability.
326 return (uint64_t)Weight * 5 > (uint64_t)Sum * 4;
Andrew Trick9e764222011-06-04 01:16:30 +0000327}
328
329BasicBlock *BranchProbabilityInfo::getHotSucc(BasicBlock *BB) const {
Andrew Trickf289df22011-06-11 01:05:22 +0000330 uint32_t Sum = 0;
331 uint32_t MaxWeight = 0;
Andrew Trick9e764222011-06-04 01:16:30 +0000332 BasicBlock *MaxSucc = 0;
333
334 for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
335 BasicBlock *Succ = *I;
Andrew Trickf289df22011-06-11 01:05:22 +0000336 uint32_t Weight = getEdgeWeight(BB, Succ);
337 uint32_t PrevSum = Sum;
Andrew Trick9e764222011-06-04 01:16:30 +0000338
339 Sum += Weight;
340 assert(Sum > PrevSum); (void) PrevSum;
341
342 if (Weight > MaxWeight) {
343 MaxWeight = Weight;
344 MaxSucc = Succ;
345 }
346 }
347
Andrew Trickf289df22011-06-11 01:05:22 +0000348 // FIXME: Use BranchProbability::compare.
349 if ((uint64_t)MaxWeight * 5 > (uint64_t)Sum * 4)
Andrew Trick9e764222011-06-04 01:16:30 +0000350 return MaxSucc;
351
352 return 0;
353}
354
355// Return edge's weight. If can't find it, return DEFAULT_WEIGHT value.
Andrew Trickf289df22011-06-11 01:05:22 +0000356uint32_t
Andrew Trick9e764222011-06-04 01:16:30 +0000357BranchProbabilityInfo::getEdgeWeight(BasicBlock *Src, BasicBlock *Dst) const {
358 Edge E(Src, Dst);
Andrew Trickf289df22011-06-11 01:05:22 +0000359 DenseMap<Edge, uint32_t>::const_iterator I = Weights.find(E);
Andrew Trick9e764222011-06-04 01:16:30 +0000360
361 if (I != Weights.end())
362 return I->second;
363
364 return DEFAULT_WEIGHT;
365}
366
367void BranchProbabilityInfo::setEdgeWeight(BasicBlock *Src, BasicBlock *Dst,
Andrew Trickf289df22011-06-11 01:05:22 +0000368 uint32_t Weight) {
Andrew Trick9e764222011-06-04 01:16:30 +0000369 Weights[std::make_pair(Src, Dst)] = Weight;
Andrew Trickf289df22011-06-11 01:05:22 +0000370 DEBUG(dbgs() << "set edge " << Src->getNameStr() << " -> "
371 << Dst->getNameStr() << " weight to " << Weight
372 << (isEdgeHot(Src, Dst) ? " [is HOT now]\n" : "\n"));
373}
374
375
376BranchProbability BranchProbabilityInfo::
377getEdgeProbability(BasicBlock *Src, BasicBlock *Dst) const {
378
379 uint32_t N = getEdgeWeight(Src, Dst);
380 uint32_t D = getSumForBlock(Src);
381
382 return BranchProbability(N, D);
Andrew Trick9e764222011-06-04 01:16:30 +0000383}
384
385raw_ostream &
386BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS, BasicBlock *Src,
Andrew Trickf289df22011-06-11 01:05:22 +0000387 BasicBlock *Dst) const {
Andrew Trick9e764222011-06-04 01:16:30 +0000388
Jakub Staszak7cc2b072011-06-16 20:22:37 +0000389 const BranchProbability Prob = getEdgeProbability(Src, Dst);
Andrew Trickf289df22011-06-11 01:05:22 +0000390 OS << "edge " << Src->getNameStr() << " -> " << Dst->getNameStr()
391 << " probability is " << Prob
392 << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
Andrew Trick9e764222011-06-04 01:16:30 +0000393
394 return OS;
395}