From a5dd5505883aa90d01d442e3a5db5aedc2277f9e Mon Sep 17 00:00:00 2001 From: Jakub Staszak Date: Sun, 31 Jul 2011 03:27:24 +0000 Subject: [PATCH] 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 --- lib/Analysis/BranchProbabilityInfo.cpp | 92 +++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/lib/Analysis/BranchProbabilityInfo.cpp b/lib/Analysis/BranchProbabilityInfo.cpp index c52a0614f04..5a7d6bf59a2 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(BB->getTerminator()); + if (!BI || !BI->isConditional()) + return false; + + Value *Cond = BI->getCondition(); + ICmpInst *CI = dyn_cast(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(LHS)) { + hasZero = CI->isZero(); + lhsZero = true; + } + + if (!hasZero) + if (ConstantInt *CI = dyn_cast(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;