diff --git a/lib/Analysis/BranchProbabilityInfo.cpp b/lib/Analysis/BranchProbabilityInfo.cpp index c37987e1be7..70de3d1c49d 100644 --- a/lib/Analysis/BranchProbabilityInfo.cpp +++ b/lib/Analysis/BranchProbabilityInfo.cpp @@ -13,6 +13,8 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" +#include "llvm/Metadata.h" #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/Debug.h" @@ -117,6 +119,9 @@ public: : BP(BP), LI(LI) { } + // Metadata Weights + bool calcMetadataWeights(BasicBlock *BB); + // Return Heuristics bool calcReturnHeuristics(BasicBlock *BB); @@ -133,6 +138,36 @@ public: }; } // end anonymous namespace +// Propagate existing explicit probabilities from either profile data or +// 'expect' intrinsic processing. +// FIXME: This doesn't correctly extract probabilities for switches. +bool BranchProbabilityAnalysis::calcMetadataWeights(BasicBlock *BB) { + BranchInst *BI = dyn_cast(BB->getTerminator()); + if (!BI || !BI->isConditional()) + return false; + + MDNode *WeightsNode = BI->getMetadata(LLVMContext::MD_prof); + if (!WeightsNode || WeightsNode->getNumOperands() < 3) + return false; + + // Pull the weights out of the metadata. Note that the zero operand is the + // name. + ConstantInt *Weights[] = { + dyn_cast(WeightsNode->getOperand(1)), + dyn_cast(WeightsNode->getOperand(2)) + }; + if (!Weights[0] || !Weights[1]) + return false; + + uint32_t WeightLimit = getMaxWeightFor(BB); + BP->setEdgeWeight(BB, BI->getSuccessor(0), + Weights[0]->getLimitedValue(WeightLimit)); + BP->setEdgeWeight(BB, BI->getSuccessor(1), + Weights[1]->getLimitedValue(WeightLimit)); + + return true; +} + // Calculate Edge Weights using "Return Heuristics". Predict a successor which // leads directly to Return Instruction will not be taken. bool BranchProbabilityAnalysis::calcReturnHeuristics(BasicBlock *BB){ @@ -341,6 +376,9 @@ bool BranchProbabilityAnalysis::runOnFunction(Function &F) { for (Function::iterator I = F.begin(), E = F.end(); I != E; ) { BasicBlock *BB = I++; + if (calcMetadataWeights(BB)) + continue; + if (calcLoopBranchHeuristics(BB)) continue; diff --git a/test/Analysis/BlockFrequencyInfo/basic.ll b/test/Analysis/BlockFrequencyInfo/basic.ll index c09e3ff03e6..f043dc08e49 100644 --- a/test/Analysis/BlockFrequencyInfo/basic.ll +++ b/test/Analysis/BlockFrequencyInfo/basic.ll @@ -22,3 +22,28 @@ body: exit: ret i32 %sum } + +define i32 @test2(i32 %i, i32 %a, i32 %b) { +; CHECK: Printing analysis {{.*}} for function 'test2' +; CHECK: entry = 1024 +entry: + %cond = icmp ult i32 %i, 42 + br i1 %cond, label %then, label %else, !prof !0 + +; The 'then' branch is predicted more likely via branch weight metadata. +; CHECK: then = 963 +then: + br label %exit + +; CHECK: else = 60 +else: + br label %exit + +; FIXME: It may be a bug that we don't sum back to 1024. +; CHECK: exit = 1023 +exit: + %result = phi i32 [ %a, %then ], [ %b, %else ] + ret i32 %result +} + +!0 = metadata !{metadata !"branch_weights", i32 64, i32 4}