blob: 52090c9fc15dcc8bb85c915d7426786306a6009d [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
Jakub Staszaka5dd5502011-07-31 03:27:24 +000014#include "llvm/Constants.h"
Andrew Trick9e764222011-06-04 01:16:30 +000015#include "llvm/Instructions.h"
Chandler Carruth99d01c52011-10-19 10:30:30 +000016#include "llvm/LLVMContext.h"
17#include "llvm/Metadata.h"
Andrew Trick9e764222011-06-04 01:16:30 +000018#include "llvm/Analysis/BranchProbabilityInfo.h"
Jakub Staszak12af93a2011-07-16 20:31:15 +000019#include "llvm/Analysis/LoopInfo.h"
Andrew Trickf289df22011-06-11 01:05:22 +000020#include "llvm/Support/Debug.h"
Andrew Trick9e764222011-06-04 01:16:30 +000021
22using namespace llvm;
23
24INITIALIZE_PASS_BEGIN(BranchProbabilityInfo, "branch-prob",
25 "Branch Probability Analysis", false, true)
26INITIALIZE_PASS_DEPENDENCY(LoopInfo)
27INITIALIZE_PASS_END(BranchProbabilityInfo, "branch-prob",
28 "Branch Probability Analysis", false, true)
29
30char BranchProbabilityInfo::ID = 0;
31
Benjamin Kramerafa88ea2011-06-13 18:38:56 +000032namespace {
Andrew Trick9e764222011-06-04 01:16:30 +000033// Please note that BranchProbabilityAnalysis is not a FunctionPass.
34// It is created by BranchProbabilityInfo (which is a FunctionPass), which
35// provides a clear interface. Thanks to that, all heuristics and other
36// private methods are hidden in the .cpp file.
37class BranchProbabilityAnalysis {
38
Jakub Staszak6f6baf12011-07-29 19:30:00 +000039 typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
Andrew Trick9e764222011-06-04 01:16:30 +000040
Andrew Trick9e764222011-06-04 01:16:30 +000041 BranchProbabilityInfo *BP;
42
43 LoopInfo *LI;
44
45
46 // Weights are for internal use only. They are used by heuristics to help to
47 // estimate edges' probability. Example:
48 //
49 // Using "Loop Branch Heuristics" we predict weights of edges for the
50 // block BB2.
51 // ...
52 // |
53 // V
54 // BB1<-+
55 // | |
Jakub Staszak3d8b15e2011-07-28 23:42:08 +000056 // | | (Weight = 124)
Andrew Trick9e764222011-06-04 01:16:30 +000057 // V |
58 // BB2--+
59 // |
60 // | (Weight = 4)
61 // V
62 // BB3
63 //
Jakub Staszak3d8b15e2011-07-28 23:42:08 +000064 // Probability of the edge BB2->BB1 = 124 / (124 + 4) = 0.96875
65 // Probability of the edge BB2->BB3 = 4 / (124 + 4) = 0.03125
Andrew Trick9e764222011-06-04 01:16:30 +000066
Jakub Staszak3d8b15e2011-07-28 23:42:08 +000067 static const uint32_t LBH_TAKEN_WEIGHT = 124;
Andrew Trickf289df22011-06-11 01:05:22 +000068 static const uint32_t LBH_NONTAKEN_WEIGHT = 4;
Andrew Trick9e764222011-06-04 01:16:30 +000069
Jakub Staszake0058b42011-07-29 02:36:53 +000070 static const uint32_t RH_TAKEN_WEIGHT = 24;
71 static const uint32_t RH_NONTAKEN_WEIGHT = 8;
72
73 static const uint32_t PH_TAKEN_WEIGHT = 20;
74 static const uint32_t PH_NONTAKEN_WEIGHT = 12;
75
Jakub Staszaka5dd5502011-07-31 03:27:24 +000076 static const uint32_t ZH_TAKEN_WEIGHT = 20;
77 static const uint32_t ZH_NONTAKEN_WEIGHT = 12;
78
Andrew Trick9e764222011-06-04 01:16:30 +000079 // Standard weight value. Used when none of the heuristics set weight for
80 // the edge.
Andrew Trickf289df22011-06-11 01:05:22 +000081 static const uint32_t NORMAL_WEIGHT = 16;
Andrew Trick9e764222011-06-04 01:16:30 +000082
83 // Minimum weight of an edge. Please note, that weight is NEVER 0.
Andrew Trickf289df22011-06-11 01:05:22 +000084 static const uint32_t MIN_WEIGHT = 1;
Andrew Trick9e764222011-06-04 01:16:30 +000085
86 // Return TRUE if BB leads directly to a Return Instruction.
87 static bool isReturningBlock(BasicBlock *BB) {
88 SmallPtrSet<BasicBlock *, 8> Visited;
89
90 while (true) {
91 TerminatorInst *TI = BB->getTerminator();
92 if (isa<ReturnInst>(TI))
93 return true;
94
95 if (TI->getNumSuccessors() > 1)
96 break;
97
98 // It is unreachable block which we can consider as a return instruction.
99 if (TI->getNumSuccessors() == 0)
100 return true;
101
102 Visited.insert(BB);
103 BB = TI->getSuccessor(0);
104
105 // Stop if cycle is detected.
106 if (Visited.count(BB))
107 return false;
108 }
109
110 return false;
111 }
112
Andrew Trickf289df22011-06-11 01:05:22 +0000113 uint32_t getMaxWeightFor(BasicBlock *BB) const {
114 return UINT32_MAX / BB->getTerminator()->getNumSuccessors();
Andrew Trick9e764222011-06-04 01:16:30 +0000115 }
116
117public:
Chandler Carruth7a34c8b2011-10-16 22:27:54 +0000118 BranchProbabilityAnalysis(BranchProbabilityInfo *BP, LoopInfo *LI)
119 : BP(BP), LI(LI) {
Andrew Trick9e764222011-06-04 01:16:30 +0000120 }
121
Chandler Carruth99d01c52011-10-19 10:30:30 +0000122 // Metadata Weights
123 bool calcMetadataWeights(BasicBlock *BB);
124
Andrew Trick9e764222011-06-04 01:16:30 +0000125 // Return Heuristics
Jakub Staszak7241caf2011-07-28 21:45:07 +0000126 bool calcReturnHeuristics(BasicBlock *BB);
Andrew Trick9e764222011-06-04 01:16:30 +0000127
128 // Pointer Heuristics
Jakub Staszak7241caf2011-07-28 21:45:07 +0000129 bool calcPointerHeuristics(BasicBlock *BB);
Andrew Trick9e764222011-06-04 01:16:30 +0000130
131 // Loop Branch Heuristics
Jakub Staszak7241caf2011-07-28 21:45:07 +0000132 bool calcLoopBranchHeuristics(BasicBlock *BB);
Andrew Trick9e764222011-06-04 01:16:30 +0000133
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000134 // Zero Heurestics
135 bool calcZeroHeuristics(BasicBlock *BB);
136
Andrew Trick9e764222011-06-04 01:16:30 +0000137 bool runOnFunction(Function &F);
138};
Benjamin Kramerafa88ea2011-06-13 18:38:56 +0000139} // end anonymous namespace
Andrew Trick9e764222011-06-04 01:16:30 +0000140
Chandler Carruth99d01c52011-10-19 10:30:30 +0000141// Propagate existing explicit probabilities from either profile data or
142// 'expect' intrinsic processing.
Chandler Carruth99d01c52011-10-19 10:30:30 +0000143bool BranchProbabilityAnalysis::calcMetadataWeights(BasicBlock *BB) {
Chandler Carruth941aa7b2011-10-19 10:32:19 +0000144 TerminatorInst *TI = BB->getTerminator();
145 if (TI->getNumSuccessors() == 1)
146 return false;
147 if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI))
Chandler Carruth99d01c52011-10-19 10:30:30 +0000148 return false;
149
Chandler Carruth941aa7b2011-10-19 10:32:19 +0000150 MDNode *WeightsNode = TI->getMetadata(LLVMContext::MD_prof);
151 if (!WeightsNode)
Chandler Carruth99d01c52011-10-19 10:30:30 +0000152 return false;
153
Chandler Carruth941aa7b2011-10-19 10:32:19 +0000154 // Ensure there are weights for all of the successors. Note that the first
155 // operand to the metadata node is a name, not a weight.
156 if (WeightsNode->getNumOperands() != TI->getNumSuccessors() + 1)
Chandler Carruth99d01c52011-10-19 10:30:30 +0000157 return false;
158
Chandler Carruth941aa7b2011-10-19 10:32:19 +0000159 // Build up the final weights that will be used in a temporary buffer, but
160 // don't add them until all weihts are present. Each weight value is clamped
161 // to [1, getMaxWeightFor(BB)].
Chandler Carruth99d01c52011-10-19 10:30:30 +0000162 uint32_t WeightLimit = getMaxWeightFor(BB);
Chandler Carruth941aa7b2011-10-19 10:32:19 +0000163 SmallVector<uint32_t, 2> Weights;
164 Weights.reserve(TI->getNumSuccessors());
165 for (unsigned i = 1, e = WeightsNode->getNumOperands(); i != e; ++i) {
166 ConstantInt *Weight = dyn_cast<ConstantInt>(WeightsNode->getOperand(i));
167 if (!Weight)
168 return false;
169 Weights.push_back(
170 std::max<uint32_t>(1, Weight->getLimitedValue(WeightLimit)));
171 }
172 assert(Weights.size() == TI->getNumSuccessors() && "Checked above");
173 for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
174 BP->setEdgeWeight(BB, TI->getSuccessor(i), Weights[i]);
Chandler Carruth99d01c52011-10-19 10:30:30 +0000175
176 return true;
177}
178
Andrew Trick9e764222011-06-04 01:16:30 +0000179// Calculate Edge Weights using "Return Heuristics". Predict a successor which
180// leads directly to Return Instruction will not be taken.
Jakub Staszak7241caf2011-07-28 21:45:07 +0000181bool BranchProbabilityAnalysis::calcReturnHeuristics(BasicBlock *BB){
Andrew Trick9e764222011-06-04 01:16:30 +0000182 if (BB->getTerminator()->getNumSuccessors() == 1)
Jakub Staszak7241caf2011-07-28 21:45:07 +0000183 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000184
Jakub Staszakb137f162011-08-01 19:16:26 +0000185 SmallPtrSet<BasicBlock *, 4> ReturningEdges;
186 SmallPtrSet<BasicBlock *, 4> StayEdges;
Jakub Staszake0058b42011-07-29 02:36:53 +0000187
Andrew Trick9e764222011-06-04 01:16:30 +0000188 for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
189 BasicBlock *Succ = *I;
Jakub Staszake0058b42011-07-29 02:36:53 +0000190 if (isReturningBlock(Succ))
Jakub Staszakb137f162011-08-01 19:16:26 +0000191 ReturningEdges.insert(Succ);
Jakub Staszake0058b42011-07-29 02:36:53 +0000192 else
Jakub Staszakb137f162011-08-01 19:16:26 +0000193 StayEdges.insert(Succ);
Jakub Staszake0058b42011-07-29 02:36:53 +0000194 }
195
196 if (uint32_t numStayEdges = StayEdges.size()) {
197 uint32_t stayWeight = RH_TAKEN_WEIGHT / numStayEdges;
198 if (stayWeight < NORMAL_WEIGHT)
199 stayWeight = NORMAL_WEIGHT;
200
Jakub Staszakb137f162011-08-01 19:16:26 +0000201 for (SmallPtrSet<BasicBlock *, 4>::iterator I = StayEdges.begin(),
Jakub Staszake0058b42011-07-29 02:36:53 +0000202 E = StayEdges.end(); I != E; ++I)
203 BP->setEdgeWeight(BB, *I, stayWeight);
204 }
205
206 if (uint32_t numRetEdges = ReturningEdges.size()) {
207 uint32_t retWeight = RH_NONTAKEN_WEIGHT / numRetEdges;
208 if (retWeight < MIN_WEIGHT)
209 retWeight = MIN_WEIGHT;
Jakub Staszakb137f162011-08-01 19:16:26 +0000210 for (SmallPtrSet<BasicBlock *, 4>::iterator I = ReturningEdges.begin(),
Jakub Staszake0058b42011-07-29 02:36:53 +0000211 E = ReturningEdges.end(); I != E; ++I) {
212 BP->setEdgeWeight(BB, *I, retWeight);
Andrew Trick9e764222011-06-04 01:16:30 +0000213 }
214 }
Jakub Staszak7241caf2011-07-28 21:45:07 +0000215
Jakub Staszake0058b42011-07-29 02:36:53 +0000216 return ReturningEdges.size() > 0;
Andrew Trick9e764222011-06-04 01:16:30 +0000217}
218
219// Calculate Edge Weights using "Pointer Heuristics". Predict a comparsion
220// between two pointer or pointer and NULL will fail.
Jakub Staszak7241caf2011-07-28 21:45:07 +0000221bool BranchProbabilityAnalysis::calcPointerHeuristics(BasicBlock *BB) {
Andrew Trick9e764222011-06-04 01:16:30 +0000222 BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator());
223 if (!BI || !BI->isConditional())
Jakub Staszak7241caf2011-07-28 21:45:07 +0000224 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000225
226 Value *Cond = BI->getCondition();
227 ICmpInst *CI = dyn_cast<ICmpInst>(Cond);
Jakub Staszakd7932ca2011-07-15 20:51:06 +0000228 if (!CI || !CI->isEquality())
Jakub Staszak7241caf2011-07-28 21:45:07 +0000229 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000230
231 Value *LHS = CI->getOperand(0);
Andrew Trick9e764222011-06-04 01:16:30 +0000232
233 if (!LHS->getType()->isPointerTy())
Jakub Staszak7241caf2011-07-28 21:45:07 +0000234 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000235
Nick Lewycky404b53e2011-06-04 02:07:10 +0000236 assert(CI->getOperand(1)->getType()->isPointerTy());
Andrew Trick9e764222011-06-04 01:16:30 +0000237
238 BasicBlock *Taken = BI->getSuccessor(0);
239 BasicBlock *NonTaken = BI->getSuccessor(1);
240
241 // p != 0 -> isProb = true
242 // p == 0 -> isProb = false
243 // p != q -> isProb = true
244 // p == q -> isProb = false;
Jakub Staszakd7932ca2011-07-15 20:51:06 +0000245 bool isProb = CI->getPredicate() == ICmpInst::ICMP_NE;
Andrew Trick9e764222011-06-04 01:16:30 +0000246 if (!isProb)
247 std::swap(Taken, NonTaken);
248
Jakub Staszake0058b42011-07-29 02:36:53 +0000249 BP->setEdgeWeight(BB, Taken, PH_TAKEN_WEIGHT);
250 BP->setEdgeWeight(BB, NonTaken, PH_NONTAKEN_WEIGHT);
Jakub Staszak7241caf2011-07-28 21:45:07 +0000251 return true;
Andrew Trick9e764222011-06-04 01:16:30 +0000252}
253
254// Calculate Edge Weights using "Loop Branch Heuristics". Predict backedges
255// as taken, exiting edges as not-taken.
Jakub Staszak7241caf2011-07-28 21:45:07 +0000256bool BranchProbabilityAnalysis::calcLoopBranchHeuristics(BasicBlock *BB) {
Andrew Trickf289df22011-06-11 01:05:22 +0000257 uint32_t numSuccs = BB->getTerminator()->getNumSuccessors();
Andrew Trick9e764222011-06-04 01:16:30 +0000258
259 Loop *L = LI->getLoopFor(BB);
260 if (!L)
Jakub Staszak7241caf2011-07-28 21:45:07 +0000261 return false;
Andrew Trick9e764222011-06-04 01:16:30 +0000262
Jakub Staszakb137f162011-08-01 19:16:26 +0000263 SmallPtrSet<BasicBlock *, 8> BackEdges;
264 SmallPtrSet<BasicBlock *, 8> ExitingEdges;
265 SmallPtrSet<BasicBlock *, 8> InEdges; // Edges from header to the loop.
Jakub Staszakfa447252011-07-28 21:33:46 +0000266
267 bool isHeader = BB == L->getHeader();
Andrew Trick9e764222011-06-04 01:16:30 +0000268
269 for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
270 BasicBlock *Succ = *I;
271 Loop *SuccL = LI->getLoopFor(Succ);
272 if (SuccL != L)
Jakub Staszakb137f162011-08-01 19:16:26 +0000273 ExitingEdges.insert(Succ);
Andrew Trick9e764222011-06-04 01:16:30 +0000274 else if (Succ == L->getHeader())
Jakub Staszakb137f162011-08-01 19:16:26 +0000275 BackEdges.insert(Succ);
Jakub Staszakfa447252011-07-28 21:33:46 +0000276 else if (isHeader)
Jakub Staszakb137f162011-08-01 19:16:26 +0000277 InEdges.insert(Succ);
Andrew Trick9e764222011-06-04 01:16:30 +0000278 }
279
Andrew Trickf289df22011-06-11 01:05:22 +0000280 if (uint32_t numBackEdges = BackEdges.size()) {
281 uint32_t backWeight = LBH_TAKEN_WEIGHT / numBackEdges;
Andrew Trick9e764222011-06-04 01:16:30 +0000282 if (backWeight < NORMAL_WEIGHT)
283 backWeight = NORMAL_WEIGHT;
284
Jakub Staszakb137f162011-08-01 19:16:26 +0000285 for (SmallPtrSet<BasicBlock *, 8>::iterator EI = BackEdges.begin(),
Andrew Trick9e764222011-06-04 01:16:30 +0000286 EE = BackEdges.end(); EI != EE; ++EI) {
287 BasicBlock *Back = *EI;
288 BP->setEdgeWeight(BB, Back, backWeight);
289 }
290 }
291
Jakub Staszakfa447252011-07-28 21:33:46 +0000292 if (uint32_t numInEdges = InEdges.size()) {
293 uint32_t inWeight = LBH_TAKEN_WEIGHT / numInEdges;
294 if (inWeight < NORMAL_WEIGHT)
295 inWeight = NORMAL_WEIGHT;
296
Jakub Staszakb137f162011-08-01 19:16:26 +0000297 for (SmallPtrSet<BasicBlock *, 8>::iterator EI = InEdges.begin(),
Jakub Staszakfa447252011-07-28 21:33:46 +0000298 EE = InEdges.end(); EI != EE; ++EI) {
299 BasicBlock *Back = *EI;
300 BP->setEdgeWeight(BB, Back, inWeight);
301 }
302 }
303
Andrew Trickf289df22011-06-11 01:05:22 +0000304 uint32_t numExitingEdges = ExitingEdges.size();
305 if (uint32_t numNonExitingEdges = numSuccs - numExitingEdges) {
306 uint32_t exitWeight = LBH_NONTAKEN_WEIGHT / numNonExitingEdges;
Andrew Trick9e764222011-06-04 01:16:30 +0000307 if (exitWeight < MIN_WEIGHT)
308 exitWeight = MIN_WEIGHT;
309
Jakub Staszakb137f162011-08-01 19:16:26 +0000310 for (SmallPtrSet<BasicBlock *, 8>::iterator EI = ExitingEdges.begin(),
Andrew Trick9e764222011-06-04 01:16:30 +0000311 EE = ExitingEdges.end(); EI != EE; ++EI) {
312 BasicBlock *Exiting = *EI;
313 BP->setEdgeWeight(BB, Exiting, exitWeight);
314 }
315 }
Jakub Staszak7241caf2011-07-28 21:45:07 +0000316
317 return true;
Andrew Trick9e764222011-06-04 01:16:30 +0000318}
319
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000320bool BranchProbabilityAnalysis::calcZeroHeuristics(BasicBlock *BB) {
321 BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator());
322 if (!BI || !BI->isConditional())
323 return false;
324
325 Value *Cond = BI->getCondition();
326 ICmpInst *CI = dyn_cast<ICmpInst>(Cond);
327 if (!CI)
328 return false;
329
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000330 Value *RHS = CI->getOperand(1);
Jakub Staszaka385c202011-07-31 04:47:20 +0000331 ConstantInt *CV = dyn_cast<ConstantInt>(RHS);
Benjamin Kramer26eb8702011-09-04 23:53:04 +0000332 if (!CV)
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000333 return false;
334
335 bool isProb;
Benjamin Kramer26eb8702011-09-04 23:53:04 +0000336 if (CV->isZero()) {
337 switch (CI->getPredicate()) {
338 case CmpInst::ICMP_EQ:
339 // X == 0 -> Unlikely
340 isProb = false;
341 break;
342 case CmpInst::ICMP_NE:
343 // X != 0 -> Likely
344 isProb = true;
345 break;
346 case CmpInst::ICMP_SLT:
347 // X < 0 -> Unlikely
348 isProb = false;
349 break;
350 case CmpInst::ICMP_SGT:
351 // X > 0 -> Likely
352 isProb = true;
353 break;
354 default:
355 return false;
356 }
357 } else if (CV->isOne() && CI->getPredicate() == CmpInst::ICMP_SLT) {
358 // InstCombine canonicalizes X <= 0 into X < 1.
359 // X <= 0 -> Unlikely
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000360 isProb = false;
Benjamin Kramer26eb8702011-09-04 23:53:04 +0000361 } else if (CV->isAllOnesValue() && CI->getPredicate() == CmpInst::ICMP_SGT) {
362 // InstCombine canonicalizes X >= 0 into X > -1.
363 // X >= 0 -> Likely
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000364 isProb = true;
Benjamin Kramer26eb8702011-09-04 23:53:04 +0000365 } else {
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000366 return false;
Benjamin Kramer26eb8702011-09-04 23:53:04 +0000367 }
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000368
369 BasicBlock *Taken = BI->getSuccessor(0);
370 BasicBlock *NonTaken = BI->getSuccessor(1);
371
372 if (!isProb)
373 std::swap(Taken, NonTaken);
374
375 BP->setEdgeWeight(BB, Taken, ZH_TAKEN_WEIGHT);
376 BP->setEdgeWeight(BB, NonTaken, ZH_NONTAKEN_WEIGHT);
377
378 return true;
379}
380
381
Andrew Trick9e764222011-06-04 01:16:30 +0000382bool BranchProbabilityAnalysis::runOnFunction(Function &F) {
383
384 for (Function::iterator I = F.begin(), E = F.end(); I != E; ) {
385 BasicBlock *BB = I++;
386
Chandler Carruth99d01c52011-10-19 10:30:30 +0000387 if (calcMetadataWeights(BB))
388 continue;
389
Jakub Staszak7241caf2011-07-28 21:45:07 +0000390 if (calcLoopBranchHeuristics(BB))
391 continue;
Andrew Trick9e764222011-06-04 01:16:30 +0000392
Jakub Staszak7241caf2011-07-28 21:45:07 +0000393 if (calcReturnHeuristics(BB))
394 continue;
395
Jakub Staszaka5dd5502011-07-31 03:27:24 +0000396 if (calcPointerHeuristics(BB))
397 continue;
398
399 calcZeroHeuristics(BB);
Andrew Trick9e764222011-06-04 01:16:30 +0000400 }
401
402 return false;
403}
404
Jakub Staszak12af93a2011-07-16 20:31:15 +0000405void BranchProbabilityInfo::getAnalysisUsage(AnalysisUsage &AU) const {
406 AU.addRequired<LoopInfo>();
407 AU.setPreservesAll();
408}
Andrew Trick9e764222011-06-04 01:16:30 +0000409
410bool BranchProbabilityInfo::runOnFunction(Function &F) {
411 LoopInfo &LI = getAnalysis<LoopInfo>();
Chandler Carruth7a34c8b2011-10-16 22:27:54 +0000412 BranchProbabilityAnalysis BPA(this, &LI);
Andrew Trickf289df22011-06-11 01:05:22 +0000413 return BPA.runOnFunction(F);
Andrew Trick9e764222011-06-04 01:16:30 +0000414}
415
Jakub Staszak6f6baf12011-07-29 19:30:00 +0000416uint32_t BranchProbabilityInfo::getSumForBlock(const BasicBlock *BB) const {
Andrew Trickf289df22011-06-11 01:05:22 +0000417 uint32_t Sum = 0;
418
Jakub Staszak6f6baf12011-07-29 19:30:00 +0000419 for (succ_const_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
420 const BasicBlock *Succ = *I;
Andrew Trickf289df22011-06-11 01:05:22 +0000421 uint32_t Weight = getEdgeWeight(BB, Succ);
422 uint32_t PrevSum = Sum;
Andrew Trick9e764222011-06-04 01:16:30 +0000423
424 Sum += Weight;
425 assert(Sum > PrevSum); (void) PrevSum;
426 }
427
Andrew Trickf289df22011-06-11 01:05:22 +0000428 return Sum;
429}
430
Jakub Staszak6f6baf12011-07-29 19:30:00 +0000431bool BranchProbabilityInfo::
432isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const {
Andrew Trickf289df22011-06-11 01:05:22 +0000433 // Hot probability is at least 4/5 = 80%
434 uint32_t Weight = getEdgeWeight(Src, Dst);
435 uint32_t Sum = getSumForBlock(Src);
436
437 // FIXME: Implement BranchProbability::compare then change this code to
438 // compare this BranchProbability against a static "hot" BranchProbability.
439 return (uint64_t)Weight * 5 > (uint64_t)Sum * 4;
Andrew Trick9e764222011-06-04 01:16:30 +0000440}
441
442BasicBlock *BranchProbabilityInfo::getHotSucc(BasicBlock *BB) const {
Andrew Trickf289df22011-06-11 01:05:22 +0000443 uint32_t Sum = 0;
444 uint32_t MaxWeight = 0;
Andrew Trick9e764222011-06-04 01:16:30 +0000445 BasicBlock *MaxSucc = 0;
446
447 for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
448 BasicBlock *Succ = *I;
Andrew Trickf289df22011-06-11 01:05:22 +0000449 uint32_t Weight = getEdgeWeight(BB, Succ);
450 uint32_t PrevSum = Sum;
Andrew Trick9e764222011-06-04 01:16:30 +0000451
452 Sum += Weight;
453 assert(Sum > PrevSum); (void) PrevSum;
454
455 if (Weight > MaxWeight) {
456 MaxWeight = Weight;
457 MaxSucc = Succ;
458 }
459 }
460
Andrew Trickf289df22011-06-11 01:05:22 +0000461 // FIXME: Use BranchProbability::compare.
462 if ((uint64_t)MaxWeight * 5 > (uint64_t)Sum * 4)
Andrew Trick9e764222011-06-04 01:16:30 +0000463 return MaxSucc;
464
465 return 0;
466}
467
468// Return edge's weight. If can't find it, return DEFAULT_WEIGHT value.
Jakub Staszak6f6baf12011-07-29 19:30:00 +0000469uint32_t BranchProbabilityInfo::
470getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const {
Andrew Trick9e764222011-06-04 01:16:30 +0000471 Edge E(Src, Dst);
Andrew Trickf289df22011-06-11 01:05:22 +0000472 DenseMap<Edge, uint32_t>::const_iterator I = Weights.find(E);
Andrew Trick9e764222011-06-04 01:16:30 +0000473
474 if (I != Weights.end())
475 return I->second;
476
477 return DEFAULT_WEIGHT;
478}
479
Jakub Staszak6f6baf12011-07-29 19:30:00 +0000480void BranchProbabilityInfo::
481setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst, uint32_t Weight) {
Andrew Trick9e764222011-06-04 01:16:30 +0000482 Weights[std::make_pair(Src, Dst)] = Weight;
Andrew Trickf289df22011-06-11 01:05:22 +0000483 DEBUG(dbgs() << "set edge " << Src->getNameStr() << " -> "
484 << Dst->getNameStr() << " weight to " << Weight
485 << (isEdgeHot(Src, Dst) ? " [is HOT now]\n" : "\n"));
486}
487
488
489BranchProbability BranchProbabilityInfo::
Jakub Staszak6f6baf12011-07-29 19:30:00 +0000490getEdgeProbability(const BasicBlock *Src, const BasicBlock *Dst) const {
Andrew Trickf289df22011-06-11 01:05:22 +0000491
492 uint32_t N = getEdgeWeight(Src, Dst);
493 uint32_t D = getSumForBlock(Src);
494
495 return BranchProbability(N, D);
Andrew Trick9e764222011-06-04 01:16:30 +0000496}
497
498raw_ostream &
499BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS, BasicBlock *Src,
Andrew Trickf289df22011-06-11 01:05:22 +0000500 BasicBlock *Dst) const {
Andrew Trick9e764222011-06-04 01:16:30 +0000501
Jakub Staszak7cc2b072011-06-16 20:22:37 +0000502 const BranchProbability Prob = getEdgeProbability(Src, Dst);
Andrew Trickf289df22011-06-11 01:05:22 +0000503 OS << "edge " << Src->getNameStr() << " -> " << Dst->getNameStr()
504 << " probability is " << Prob
505 << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
Andrew Trick9e764222011-06-04 01:16:30 +0000506
507 return OS;
508}