aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-10-19 10:30:30 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-10-19 10:30:30 +0000
commit99d01c54a0fd790a48d5aa02bfeb4cc08388b8fa (patch)
treef937b9c7d85eece81dbc1f73370dfb26006570ae
parent6aa5c26c81071e22a23a6f0ae7dcac6080ad6597 (diff)
Teach the BranchProbabilityInfo analysis pass to read any metadata
encoding of probabilities. In the absense of metadata, it continues to fall back on static heuristics. This allows __builtin_expect, after lowering through llvm.expect a branch instruction's metadata, to actually enter the branch probability model. This is one component of resolving PR2577. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142492 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/BranchProbabilityInfo.cpp38
-rw-r--r--test/Analysis/BlockFrequencyInfo/basic.ll25
2 files changed, 63 insertions, 0 deletions
diff --git a/lib/Analysis/BranchProbabilityInfo.cpp b/lib/Analysis/BranchProbabilityInfo.cpp
index c37987e1be..70de3d1c49 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<BranchInst>(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<ConstantInt>(WeightsNode->getOperand(1)),
+ dyn_cast<ConstantInt>(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 c09e3ff03e..f043dc08e4 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}