diff options
author | Jakub Staszak <jstaszak@apple.com> | 2011-07-31 03:27:24 +0000 |
---|---|---|
committer | Jakub Staszak <jstaszak@apple.com> | 2011-07-31 03:27:24 +0000 |
commit | a5dd5505883aa90d01d442e3a5db5aedc2277f9e (patch) | |
tree | ee5620a8483049f77389804417f6167442beda6e /lib/Analysis/BranchProbabilityInfo.cpp | |
parent | e2721f75503d9195d02b8d2dc4d196b9256873e9 (diff) |
Add Zero Heurestics to BranchProbabilityInfo. If we compare value to zero we
decide whether condition is likely to be true this way:
x == 0 -> false
x < 0 -> false
x <= 0 -> false
x != 0 -> true
x > 0 -> true
x >= 0 -> true
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136583 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BranchProbabilityInfo.cpp')
-rw-r--r-- | lib/Analysis/BranchProbabilityInfo.cpp | 92 |
1 files changed, 91 insertions, 1 deletions
diff --git a/lib/Analysis/BranchProbabilityInfo.cpp b/lib/Analysis/BranchProbabilityInfo.cpp index c52a0614f0..5a7d6bf59a 100644 --- a/lib/Analysis/BranchProbabilityInfo.cpp +++ b/lib/Analysis/BranchProbabilityInfo.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/LoopInfo.h" @@ -72,6 +73,9 @@ class BranchProbabilityAnalysis { static const uint32_t PH_TAKEN_WEIGHT = 20; static const uint32_t PH_NONTAKEN_WEIGHT = 12; + static const uint32_t ZH_TAKEN_WEIGHT = 20; + static const uint32_t ZH_NONTAKEN_WEIGHT = 12; + // Standard weight value. Used when none of the heuristics set weight for // the edge. static const uint32_t NORMAL_WEIGHT = 16; @@ -125,6 +129,9 @@ public: // Loop Branch Heuristics bool calcLoopBranchHeuristics(BasicBlock *BB); + // Zero Heurestics + bool calcZeroHeuristics(BasicBlock *BB); + bool runOnFunction(Function &F); }; } // end anonymous namespace @@ -270,6 +277,86 @@ bool BranchProbabilityAnalysis::calcLoopBranchHeuristics(BasicBlock *BB) { return true; } +bool BranchProbabilityAnalysis::calcZeroHeuristics(BasicBlock *BB) { + BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); + if (!BI || !BI->isConditional()) + return false; + + Value *Cond = BI->getCondition(); + ICmpInst *CI = dyn_cast<ICmpInst>(Cond); + if (!CI) + return false; + + Value *LHS = CI->getOperand(0); + Value *RHS = CI->getOperand(1); + + bool hasZero = false; + bool lhsZero = false; + if (ConstantInt *CI = dyn_cast<ConstantInt>(LHS)) { + hasZero = CI->isZero(); + lhsZero = true; + } + + if (!hasZero) + if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) + hasZero = CI->isZero(); + + if (!hasZero) + return false; + + bool isProb; + switch (CI->getPredicate()) { + case CmpInst::ICMP_EQ: + // Equal to zero is not expected to be taken. + isProb = false; + break; + + case CmpInst::ICMP_NE: + // Not equal to zero is expected. + isProb = true; + break; + + case CmpInst::ICMP_ULT: + case CmpInst::ICMP_ULE: + case CmpInst::ICMP_SLT: + case CmpInst::ICMP_SLE: + // Less or equal to zero is not expected. + // 0 < X -> isProb = true + // 0 <= X -> isProb = true + // X < 0 -> isProb = false + // X <= 0 -> isProb = false + isProb = lhsZero; + break; + + case CmpInst::ICMP_UGT: + case CmpInst::ICMP_UGE: + case CmpInst::ICMP_SGT: + case CmpInst::ICMP_SGE: + // Greater or equal to zero is expected. + // 0 > X -> isProb = false + // 0 >= X -> isProb = false + // X > 0 -> isProb = true + // X >= 0 -> isProb = true + isProb = !lhsZero; + break; + + default: + return false; + }; + + BasicBlock *Taken = BI->getSuccessor(0); + BasicBlock *NonTaken = BI->getSuccessor(1); + + if (!isProb) + std::swap(Taken, NonTaken); + + BP->setEdgeWeight(BB, Taken, ZH_TAKEN_WEIGHT); + BP->setEdgeWeight(BB, NonTaken, ZH_NONTAKEN_WEIGHT); + + return true; +} + + bool BranchProbabilityAnalysis::runOnFunction(Function &F) { for (Function::iterator I = F.begin(), E = F.end(); I != E; ) { @@ -284,7 +371,10 @@ bool BranchProbabilityAnalysis::runOnFunction(Function &F) { if (calcReturnHeuristics(BB)) continue; - calcPointerHeuristics(BB); + if (calcPointerHeuristics(BB)) + continue; + + calcZeroHeuristics(BB); } return false; |