diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp | 77 | 
1 files changed, 58 insertions, 19 deletions
| diff --git a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp index 53671c7bc3d1..0fe7dd9cfb39 100644 --- a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp +++ b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp @@ -55,13 +55,35 @@ static cl::opt<uint32_t> UnlikelyBranchWeight(      "unlikely-branch-weight", cl::Hidden, cl::init(1),      cl::desc("Weight of the branch unlikely to be taken (default = 1)")); +static std::tuple<uint32_t, uint32_t> +getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount) { +  if (IntrinsicID == Intrinsic::expect) { +    // __builtin_expect +    return std::make_tuple(LikelyBranchWeight.getValue(), +                           UnlikelyBranchWeight.getValue()); +  } else { +    // __builtin_expect_with_probability +    assert(CI->getNumOperands() >= 3 && +           "expect with probability must have 3 arguments"); +    ConstantFP *Confidence = dyn_cast<ConstantFP>(CI->getArgOperand(2)); +    double TrueProb = Confidence->getValueAPF().convertToDouble(); +    assert((TrueProb >= 0.0 && TrueProb <= 1.0) && +           "probability value must be in the range [0.0, 1.0]"); +    double FalseProb = (1.0 - TrueProb) / (BranchCount - 1); +    uint32_t LikelyBW = ceil((TrueProb * (double)(INT32_MAX - 1)) + 1.0); +    uint32_t UnlikelyBW = ceil((FalseProb * (double)(INT32_MAX - 1)) + 1.0); +    return std::make_tuple(LikelyBW, UnlikelyBW); +  } +} +  static bool handleSwitchExpect(SwitchInst &SI) {    CallInst *CI = dyn_cast<CallInst>(SI.getCondition());    if (!CI)      return false;    Function *Fn = CI->getCalledFunction(); -  if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) +  if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect && +              Fn->getIntrinsicID() != Intrinsic::expect_with_probability))      return false;    Value *ArgValue = CI->getArgOperand(0); @@ -71,15 +93,19 @@ static bool handleSwitchExpect(SwitchInst &SI) {    SwitchInst::CaseHandle Case = *SI.findCaseValue(ExpectedValue);    unsigned n = SI.getNumCases(); // +1 for default case. -  SmallVector<uint32_t, 16> Weights(n + 1, UnlikelyBranchWeight); +  uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal; +  std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) = +      getBranchWeight(Fn->getIntrinsicID(), CI, n + 1); + +  SmallVector<uint32_t, 16> Weights(n + 1, UnlikelyBranchWeightVal);    uint64_t Index = (Case == *SI.case_default()) ? 0 : Case.getCaseIndex() + 1; -  Weights[Index] = LikelyBranchWeight; +  Weights[Index] = LikelyBranchWeightVal; -  SI.setMetadata( -      LLVMContext::MD_misexpect, -      MDBuilder(CI->getContext()) -          .createMisExpect(Index, LikelyBranchWeight, UnlikelyBranchWeight)); +  SI.setMetadata(LLVMContext::MD_misexpect, +                 MDBuilder(CI->getContext()) +                     .createMisExpect(Index, LikelyBranchWeightVal, +                                      UnlikelyBranchWeightVal));    SI.setCondition(ArgValue);    misexpect::checkFrontendInstrumentation(SI); @@ -223,15 +249,18 @@ static void handlePhiDef(CallInst *Expect) {          return true;        return false;      }; +    uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal; +    std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) = getBranchWeight( +        Expect->getCalledFunction()->getIntrinsicID(), Expect, 2);      if (IsOpndComingFromSuccessor(BI->getSuccessor(1))) -      BI->setMetadata( -          LLVMContext::MD_prof, -          MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight)); +      BI->setMetadata(LLVMContext::MD_prof, +                      MDB.createBranchWeights(LikelyBranchWeightVal, +                                              UnlikelyBranchWeightVal));      else if (IsOpndComingFromSuccessor(BI->getSuccessor(0))) -      BI->setMetadata( -          LLVMContext::MD_prof, -          MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight)); +      BI->setMetadata(LLVMContext::MD_prof, +                      MDB.createBranchWeights(UnlikelyBranchWeightVal, +                                              LikelyBranchWeightVal));    }  } @@ -277,7 +306,8 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {    }    Function *Fn = CI->getCalledFunction(); -  if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) +  if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect && +              Fn->getIntrinsicID() != Intrinsic::expect_with_probability))      return false;    Value *ArgValue = CI->getArgOperand(0); @@ -289,13 +319,21 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {    MDNode *Node;    MDNode *ExpNode; +  uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal; +  std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) = +      getBranchWeight(Fn->getIntrinsicID(), CI, 2); +    if ((ExpectedValue->getZExtValue() == ValueComparedTo) ==        (Predicate == CmpInst::ICMP_EQ)) { -    Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight); -    ExpNode = MDB.createMisExpect(0, LikelyBranchWeight, UnlikelyBranchWeight); +    Node = +        MDB.createBranchWeights(LikelyBranchWeightVal, UnlikelyBranchWeightVal); +    ExpNode = +        MDB.createMisExpect(0, LikelyBranchWeightVal, UnlikelyBranchWeightVal);    } else { -    Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); -    ExpNode = MDB.createMisExpect(1, LikelyBranchWeight, UnlikelyBranchWeight); +    Node = +        MDB.createBranchWeights(UnlikelyBranchWeightVal, LikelyBranchWeightVal); +    ExpNode = +        MDB.createMisExpect(1, LikelyBranchWeightVal, UnlikelyBranchWeightVal);    }    BSI.setMetadata(LLVMContext::MD_misexpect, ExpNode); @@ -347,7 +385,8 @@ static bool lowerExpectIntrinsic(Function &F) {        }        Function *Fn = CI->getCalledFunction(); -      if (Fn && Fn->getIntrinsicID() == Intrinsic::expect) { +      if (Fn && (Fn->getIntrinsicID() == Intrinsic::expect || +                 Fn->getIntrinsicID() == Intrinsic::expect_with_probability)) {          // Before erasing the llvm.expect, walk backward to find          // phi that define llvm.expect's first arg, and          // infer branch probability: | 
