xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- LowerExpectIntrinsic.cpp - Lower expect intrinsic ------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This pass lowers the 'expect' intrinsic to LLVM metadata.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
140b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
150b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
160b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
170b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
180b57cec5SDimitry Andric #include "llvm/IR/Function.h"
190b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
200b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
210b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
220b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
235f757f3fSDimitry Andric #include "llvm/IR/ProfDataUtils.h"
24fe6060f1SDimitry Andric #include "llvm/Support/CommandLine.h"
2581ad6265SDimitry Andric #include "llvm/Transforms/Utils/MisExpect.h"
260b57cec5SDimitry Andric 
27bdd1243dSDimitry Andric #include <cmath>
28bdd1243dSDimitry Andric 
290b57cec5SDimitry Andric using namespace llvm;
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric #define DEBUG_TYPE "lower-expect-intrinsic"
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric STATISTIC(ExpectIntrinsicsHandled,
340b57cec5SDimitry Andric           "Number of 'expect' intrinsic instructions handled");
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric // These default values are chosen to represent an extremely skewed outcome for
370b57cec5SDimitry Andric // a condition, but they leave some room for interpretation by later passes.
380b57cec5SDimitry Andric //
390b57cec5SDimitry Andric // If the documentation for __builtin_expect() was made explicit that it should
400b57cec5SDimitry Andric // only be used in extreme cases, we could make this ratio higher. As it stands,
410b57cec5SDimitry Andric // programmers may be using __builtin_expect() / llvm.expect to annotate that a
420b57cec5SDimitry Andric // branch is likely or unlikely to be taken.
430b57cec5SDimitry Andric 
44fe6060f1SDimitry Andric // WARNING: these values are internal implementation detail of the pass.
45fe6060f1SDimitry Andric // They should not be exposed to the outside of the pass, front-end codegen
46fe6060f1SDimitry Andric // should emit @llvm.expect intrinsics instead of using these weights directly.
47fe6060f1SDimitry Andric // Transforms should use TargetTransformInfo's getPredictableBranchThreshold().
48fe6060f1SDimitry Andric static cl::opt<uint32_t> LikelyBranchWeight(
490b57cec5SDimitry Andric     "likely-branch-weight", cl::Hidden, cl::init(2000),
500b57cec5SDimitry Andric     cl::desc("Weight of the branch likely to be taken (default = 2000)"));
51fe6060f1SDimitry Andric static cl::opt<uint32_t> UnlikelyBranchWeight(
520b57cec5SDimitry Andric     "unlikely-branch-weight", cl::Hidden, cl::init(1),
530b57cec5SDimitry Andric     cl::desc("Weight of the branch unlikely to be taken (default = 1)"));
540b57cec5SDimitry Andric 
555ffd83dbSDimitry Andric static std::tuple<uint32_t, uint32_t>
565ffd83dbSDimitry Andric getBranchWeight(Intrinsic::ID IntrinsicID, CallInst *CI, int BranchCount) {
575ffd83dbSDimitry Andric   if (IntrinsicID == Intrinsic::expect) {
585ffd83dbSDimitry Andric     // __builtin_expect
595ffd83dbSDimitry Andric     return std::make_tuple(LikelyBranchWeight.getValue(),
605ffd83dbSDimitry Andric                            UnlikelyBranchWeight.getValue());
615ffd83dbSDimitry Andric   } else {
625ffd83dbSDimitry Andric     // __builtin_expect_with_probability
635ffd83dbSDimitry Andric     assert(CI->getNumOperands() >= 3 &&
645ffd83dbSDimitry Andric            "expect with probability must have 3 arguments");
6504eeddc0SDimitry Andric     auto *Confidence = cast<ConstantFP>(CI->getArgOperand(2));
665ffd83dbSDimitry Andric     double TrueProb = Confidence->getValueAPF().convertToDouble();
675ffd83dbSDimitry Andric     assert((TrueProb >= 0.0 && TrueProb <= 1.0) &&
685ffd83dbSDimitry Andric            "probability value must be in the range [0.0, 1.0]");
695ffd83dbSDimitry Andric     double FalseProb = (1.0 - TrueProb) / (BranchCount - 1);
705ffd83dbSDimitry Andric     uint32_t LikelyBW = ceil((TrueProb * (double)(INT32_MAX - 1)) + 1.0);
715ffd83dbSDimitry Andric     uint32_t UnlikelyBW = ceil((FalseProb * (double)(INT32_MAX - 1)) + 1.0);
725ffd83dbSDimitry Andric     return std::make_tuple(LikelyBW, UnlikelyBW);
735ffd83dbSDimitry Andric   }
745ffd83dbSDimitry Andric }
755ffd83dbSDimitry Andric 
760b57cec5SDimitry Andric static bool handleSwitchExpect(SwitchInst &SI) {
770b57cec5SDimitry Andric   CallInst *CI = dyn_cast<CallInst>(SI.getCondition());
780b57cec5SDimitry Andric   if (!CI)
790b57cec5SDimitry Andric     return false;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   Function *Fn = CI->getCalledFunction();
825ffd83dbSDimitry Andric   if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect &&
835ffd83dbSDimitry Andric               Fn->getIntrinsicID() != Intrinsic::expect_with_probability))
840b57cec5SDimitry Andric     return false;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   Value *ArgValue = CI->getArgOperand(0);
870b57cec5SDimitry Andric   ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
880b57cec5SDimitry Andric   if (!ExpectedValue)
890b57cec5SDimitry Andric     return false;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   SwitchInst::CaseHandle Case = *SI.findCaseValue(ExpectedValue);
920b57cec5SDimitry Andric   unsigned n = SI.getNumCases(); // +1 for default case.
935ffd83dbSDimitry Andric   uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
945ffd83dbSDimitry Andric   std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
955ffd83dbSDimitry Andric       getBranchWeight(Fn->getIntrinsicID(), CI, n + 1);
965ffd83dbSDimitry Andric 
975ffd83dbSDimitry Andric   SmallVector<uint32_t, 16> Weights(n + 1, UnlikelyBranchWeightVal);
980b57cec5SDimitry Andric 
998bcb0991SDimitry Andric   uint64_t Index = (Case == *SI.case_default()) ? 0 : Case.getCaseIndex() + 1;
1005ffd83dbSDimitry Andric   Weights[Index] = LikelyBranchWeightVal;
1018bcb0991SDimitry Andric 
10281ad6265SDimitry Andric   misexpect::checkExpectAnnotations(SI, Weights, /*IsFrontend=*/true);
10381ad6265SDimitry Andric 
1048bcb0991SDimitry Andric   SI.setCondition(ArgValue);
105*0fca6ea1SDimitry Andric   setBranchWeights(SI, Weights, /*IsExpected=*/true);
1060b57cec5SDimitry Andric   return true;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric /// Handler for PHINodes that define the value argument to an
1100b57cec5SDimitry Andric /// @llvm.expect call.
1110b57cec5SDimitry Andric ///
1120b57cec5SDimitry Andric /// If the operand of the phi has a constant value and it 'contradicts'
1130b57cec5SDimitry Andric /// with the expected value of phi def, then the corresponding incoming
1140b57cec5SDimitry Andric /// edge of the phi is unlikely to be taken. Using that information,
1150b57cec5SDimitry Andric /// the branch probability info for the originating branch can be inferred.
1160b57cec5SDimitry Andric static void handlePhiDef(CallInst *Expect) {
1170b57cec5SDimitry Andric   Value &Arg = *Expect->getArgOperand(0);
1180b57cec5SDimitry Andric   ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(Expect->getArgOperand(1));
1190b57cec5SDimitry Andric   if (!ExpectedValue)
1200b57cec5SDimitry Andric     return;
1210b57cec5SDimitry Andric   const APInt &ExpectedPhiValue = ExpectedValue->getValue();
122bdd1243dSDimitry Andric   bool ExpectedValueIsLikely = true;
123bdd1243dSDimitry Andric   Function *Fn = Expect->getCalledFunction();
124bdd1243dSDimitry Andric   // If the function is expect_with_probability, then we need to take the
125bdd1243dSDimitry Andric   // probability into consideration. For example, in
126bdd1243dSDimitry Andric   // expect.with.probability.i64(i64 %a, i64 1, double 0.0), the
127bdd1243dSDimitry Andric   // "ExpectedValue" 1 is unlikely. This affects probability propagation later.
128bdd1243dSDimitry Andric   if (Fn->getIntrinsicID() == Intrinsic::expect_with_probability) {
129bdd1243dSDimitry Andric     auto *Confidence = cast<ConstantFP>(Expect->getArgOperand(2));
130bdd1243dSDimitry Andric     double TrueProb = Confidence->getValueAPF().convertToDouble();
131bdd1243dSDimitry Andric     ExpectedValueIsLikely = (TrueProb > 0.5);
132bdd1243dSDimitry Andric   }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   // Walk up in backward a list of instructions that
1350b57cec5SDimitry Andric   // have 'copy' semantics by 'stripping' the copies
1360b57cec5SDimitry Andric   // until a PHI node or an instruction of unknown kind
1370b57cec5SDimitry Andric   // is reached. Negation via xor is also handled.
1380b57cec5SDimitry Andric   //
1390b57cec5SDimitry Andric   //       C = PHI(...);
1400b57cec5SDimitry Andric   //       B = C;
1410b57cec5SDimitry Andric   //       A = B;
1420b57cec5SDimitry Andric   //       D = __builtin_expect(A, 0);
1430b57cec5SDimitry Andric   //
1440b57cec5SDimitry Andric   Value *V = &Arg;
1450b57cec5SDimitry Andric   SmallVector<Instruction *, 4> Operations;
1460b57cec5SDimitry Andric   while (!isa<PHINode>(V)) {
1470b57cec5SDimitry Andric     if (ZExtInst *ZExt = dyn_cast<ZExtInst>(V)) {
1480b57cec5SDimitry Andric       V = ZExt->getOperand(0);
1490b57cec5SDimitry Andric       Operations.push_back(ZExt);
1500b57cec5SDimitry Andric       continue;
1510b57cec5SDimitry Andric     }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric     if (SExtInst *SExt = dyn_cast<SExtInst>(V)) {
1540b57cec5SDimitry Andric       V = SExt->getOperand(0);
1550b57cec5SDimitry Andric       Operations.push_back(SExt);
1560b57cec5SDimitry Andric       continue;
1570b57cec5SDimitry Andric     }
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric     BinaryOperator *BinOp = dyn_cast<BinaryOperator>(V);
1600b57cec5SDimitry Andric     if (!BinOp || BinOp->getOpcode() != Instruction::Xor)
1610b57cec5SDimitry Andric       return;
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric     ConstantInt *CInt = dyn_cast<ConstantInt>(BinOp->getOperand(1));
1640b57cec5SDimitry Andric     if (!CInt)
1650b57cec5SDimitry Andric       return;
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric     V = BinOp->getOperand(0);
1680b57cec5SDimitry Andric     Operations.push_back(BinOp);
1690b57cec5SDimitry Andric   }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   // Executes the recorded operations on input 'Value'.
1720b57cec5SDimitry Andric   auto ApplyOperations = [&](const APInt &Value) {
1730b57cec5SDimitry Andric     APInt Result = Value;
174bdd1243dSDimitry Andric     for (auto *Op : llvm::reverse(Operations)) {
1750b57cec5SDimitry Andric       switch (Op->getOpcode()) {
1760b57cec5SDimitry Andric       case Instruction::Xor:
1770b57cec5SDimitry Andric         Result ^= cast<ConstantInt>(Op->getOperand(1))->getValue();
1780b57cec5SDimitry Andric         break;
1790b57cec5SDimitry Andric       case Instruction::ZExt:
1800b57cec5SDimitry Andric         Result = Result.zext(Op->getType()->getIntegerBitWidth());
1810b57cec5SDimitry Andric         break;
1820b57cec5SDimitry Andric       case Instruction::SExt:
1830b57cec5SDimitry Andric         Result = Result.sext(Op->getType()->getIntegerBitWidth());
1840b57cec5SDimitry Andric         break;
1850b57cec5SDimitry Andric       default:
1860b57cec5SDimitry Andric         llvm_unreachable("Unexpected operation");
1870b57cec5SDimitry Andric       }
1880b57cec5SDimitry Andric     }
1890b57cec5SDimitry Andric     return Result;
1900b57cec5SDimitry Andric   };
1910b57cec5SDimitry Andric 
1928bcb0991SDimitry Andric   auto *PhiDef = cast<PHINode>(V);
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric   // Get the first dominating conditional branch of the operand
1950b57cec5SDimitry Andric   // i's incoming block.
1960b57cec5SDimitry Andric   auto GetDomConditional = [&](unsigned i) -> BranchInst * {
1970b57cec5SDimitry Andric     BasicBlock *BB = PhiDef->getIncomingBlock(i);
1980b57cec5SDimitry Andric     BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
1990b57cec5SDimitry Andric     if (BI && BI->isConditional())
2000b57cec5SDimitry Andric       return BI;
2010b57cec5SDimitry Andric     BB = BB->getSinglePredecessor();
2020b57cec5SDimitry Andric     if (!BB)
2030b57cec5SDimitry Andric       return nullptr;
2040b57cec5SDimitry Andric     BI = dyn_cast<BranchInst>(BB->getTerminator());
2050b57cec5SDimitry Andric     if (!BI || BI->isUnconditional())
2060b57cec5SDimitry Andric       return nullptr;
2070b57cec5SDimitry Andric     return BI;
2080b57cec5SDimitry Andric   };
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   // Now walk through all Phi operands to find phi oprerands with values
2110b57cec5SDimitry Andric   // conflicting with the expected phi output value. Any such operand
2120b57cec5SDimitry Andric   // indicates the incoming edge to that operand is unlikely.
2130b57cec5SDimitry Andric   for (unsigned i = 0, e = PhiDef->getNumIncomingValues(); i != e; ++i) {
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric     Value *PhiOpnd = PhiDef->getIncomingValue(i);
2160b57cec5SDimitry Andric     ConstantInt *CI = dyn_cast<ConstantInt>(PhiOpnd);
2170b57cec5SDimitry Andric     if (!CI)
2180b57cec5SDimitry Andric       continue;
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric     // Not an interesting case when IsUnlikely is false -- we can not infer
221bdd1243dSDimitry Andric     // anything useful when:
222bdd1243dSDimitry Andric     // (1) We expect some phi output and the operand value matches it, or
223bdd1243dSDimitry Andric     // (2) We don't expect some phi output (i.e. the "ExpectedValue" has low
224bdd1243dSDimitry Andric     //     probability) and the operand value doesn't match that.
225bdd1243dSDimitry Andric     const APInt &CurrentPhiValue = ApplyOperations(CI->getValue());
226bdd1243dSDimitry Andric     if (ExpectedValueIsLikely == (ExpectedPhiValue == CurrentPhiValue))
2270b57cec5SDimitry Andric       continue;
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric     BranchInst *BI = GetDomConditional(i);
2300b57cec5SDimitry Andric     if (!BI)
2310b57cec5SDimitry Andric       continue;
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric     MDBuilder MDB(PhiDef->getContext());
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric     // There are two situations in which an operand of the PhiDef comes
2360b57cec5SDimitry Andric     // from a given successor of a branch instruction BI.
2370b57cec5SDimitry Andric     // 1) When the incoming block of the operand is the successor block;
2380b57cec5SDimitry Andric     // 2) When the incoming block is BI's enclosing block and the
2390b57cec5SDimitry Andric     // successor is the PhiDef's enclosing block.
2400b57cec5SDimitry Andric     //
2410b57cec5SDimitry Andric     // Returns true if the operand which comes from OpndIncomingBB
2420b57cec5SDimitry Andric     // comes from outgoing edge of BI that leads to Succ block.
2430b57cec5SDimitry Andric     auto *OpndIncomingBB = PhiDef->getIncomingBlock(i);
2440b57cec5SDimitry Andric     auto IsOpndComingFromSuccessor = [&](BasicBlock *Succ) {
2450b57cec5SDimitry Andric       if (OpndIncomingBB == Succ)
2460b57cec5SDimitry Andric         // If this successor is the incoming block for this
2470b57cec5SDimitry Andric         // Phi operand, then this successor does lead to the Phi.
2480b57cec5SDimitry Andric         return true;
2490b57cec5SDimitry Andric       if (OpndIncomingBB == BI->getParent() && Succ == PhiDef->getParent())
2500b57cec5SDimitry Andric         // Otherwise, if the edge is directly from the branch
2510b57cec5SDimitry Andric         // to the Phi, this successor is the one feeding this
2520b57cec5SDimitry Andric         // Phi operand.
2530b57cec5SDimitry Andric         return true;
2540b57cec5SDimitry Andric       return false;
2550b57cec5SDimitry Andric     };
2565ffd83dbSDimitry Andric     uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
2575ffd83dbSDimitry Andric     std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) = getBranchWeight(
2585ffd83dbSDimitry Andric         Expect->getCalledFunction()->getIntrinsicID(), Expect, 2);
259bdd1243dSDimitry Andric     if (!ExpectedValueIsLikely)
260bdd1243dSDimitry Andric       std::swap(LikelyBranchWeightVal, UnlikelyBranchWeightVal);
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric     if (IsOpndComingFromSuccessor(BI->getSuccessor(1)))
2635ffd83dbSDimitry Andric       BI->setMetadata(LLVMContext::MD_prof,
2645ffd83dbSDimitry Andric                       MDB.createBranchWeights(LikelyBranchWeightVal,
265*0fca6ea1SDimitry Andric                                               UnlikelyBranchWeightVal,
266*0fca6ea1SDimitry Andric                                               /*IsExpected=*/true));
2670b57cec5SDimitry Andric     else if (IsOpndComingFromSuccessor(BI->getSuccessor(0)))
2685ffd83dbSDimitry Andric       BI->setMetadata(LLVMContext::MD_prof,
2695ffd83dbSDimitry Andric                       MDB.createBranchWeights(UnlikelyBranchWeightVal,
270*0fca6ea1SDimitry Andric                                               LikelyBranchWeightVal,
271*0fca6ea1SDimitry Andric                                               /*IsExpected=*/true));
2720b57cec5SDimitry Andric   }
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric // Handle both BranchInst and SelectInst.
2760b57cec5SDimitry Andric template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) {
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric   // Handle non-optimized IR code like:
2790b57cec5SDimitry Andric   //   %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1)
2800b57cec5SDimitry Andric   //   %tobool = icmp ne i64 %expval, 0
2810b57cec5SDimitry Andric   //   br i1 %tobool, label %if.then, label %if.end
2820b57cec5SDimitry Andric   //
2830b57cec5SDimitry Andric   // Or the following simpler case:
2840b57cec5SDimitry Andric   //   %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1)
2850b57cec5SDimitry Andric   //   br i1 %expval, label %if.then, label %if.end
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   CallInst *CI;
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric   ICmpInst *CmpI = dyn_cast<ICmpInst>(BSI.getCondition());
2900b57cec5SDimitry Andric   CmpInst::Predicate Predicate;
2910b57cec5SDimitry Andric   ConstantInt *CmpConstOperand = nullptr;
2920b57cec5SDimitry Andric   if (!CmpI) {
2930b57cec5SDimitry Andric     CI = dyn_cast<CallInst>(BSI.getCondition());
2940b57cec5SDimitry Andric     Predicate = CmpInst::ICMP_NE;
2950b57cec5SDimitry Andric   } else {
2960b57cec5SDimitry Andric     Predicate = CmpI->getPredicate();
2970b57cec5SDimitry Andric     if (Predicate != CmpInst::ICMP_NE && Predicate != CmpInst::ICMP_EQ)
2980b57cec5SDimitry Andric       return false;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric     CmpConstOperand = dyn_cast<ConstantInt>(CmpI->getOperand(1));
3010b57cec5SDimitry Andric     if (!CmpConstOperand)
3020b57cec5SDimitry Andric       return false;
3030b57cec5SDimitry Andric     CI = dyn_cast<CallInst>(CmpI->getOperand(0));
3040b57cec5SDimitry Andric   }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   if (!CI)
3070b57cec5SDimitry Andric     return false;
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   uint64_t ValueComparedTo = 0;
3100b57cec5SDimitry Andric   if (CmpConstOperand) {
3110b57cec5SDimitry Andric     if (CmpConstOperand->getBitWidth() > 64)
3120b57cec5SDimitry Andric       return false;
3130b57cec5SDimitry Andric     ValueComparedTo = CmpConstOperand->getZExtValue();
3140b57cec5SDimitry Andric   }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   Function *Fn = CI->getCalledFunction();
3175ffd83dbSDimitry Andric   if (!Fn || (Fn->getIntrinsicID() != Intrinsic::expect &&
3185ffd83dbSDimitry Andric               Fn->getIntrinsicID() != Intrinsic::expect_with_probability))
3190b57cec5SDimitry Andric     return false;
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   Value *ArgValue = CI->getArgOperand(0);
3220b57cec5SDimitry Andric   ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1));
3230b57cec5SDimitry Andric   if (!ExpectedValue)
3240b57cec5SDimitry Andric     return false;
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   MDBuilder MDB(CI->getContext());
3270b57cec5SDimitry Andric   MDNode *Node;
3280b57cec5SDimitry Andric 
3295ffd83dbSDimitry Andric   uint32_t LikelyBranchWeightVal, UnlikelyBranchWeightVal;
3305ffd83dbSDimitry Andric   std::tie(LikelyBranchWeightVal, UnlikelyBranchWeightVal) =
3315ffd83dbSDimitry Andric       getBranchWeight(Fn->getIntrinsicID(), CI, 2);
3325ffd83dbSDimitry Andric 
33381ad6265SDimitry Andric   SmallVector<uint32_t, 4> ExpectedWeights;
3340b57cec5SDimitry Andric   if ((ExpectedValue->getZExtValue() == ValueComparedTo) ==
3358bcb0991SDimitry Andric       (Predicate == CmpInst::ICMP_EQ)) {
336*0fca6ea1SDimitry Andric     Node = MDB.createBranchWeights(
337*0fca6ea1SDimitry Andric         LikelyBranchWeightVal, UnlikelyBranchWeightVal, /*IsExpected=*/true);
33881ad6265SDimitry Andric     ExpectedWeights = {LikelyBranchWeightVal, UnlikelyBranchWeightVal};
3398bcb0991SDimitry Andric   } else {
340*0fca6ea1SDimitry Andric     Node = MDB.createBranchWeights(UnlikelyBranchWeightVal,
341*0fca6ea1SDimitry Andric                                    LikelyBranchWeightVal, /*IsExpected=*/true);
34281ad6265SDimitry Andric     ExpectedWeights = {UnlikelyBranchWeightVal, LikelyBranchWeightVal};
3438bcb0991SDimitry Andric   }
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric   if (CmpI)
3460b57cec5SDimitry Andric     CmpI->setOperand(0, ArgValue);
3470b57cec5SDimitry Andric   else
3480b57cec5SDimitry Andric     BSI.setCondition(ArgValue);
3498bcb0991SDimitry Andric 
35081ad6265SDimitry Andric   misexpect::checkFrontendInstrumentation(BSI, ExpectedWeights);
35181ad6265SDimitry Andric 
3528bcb0991SDimitry Andric   BSI.setMetadata(LLVMContext::MD_prof, Node);
3538bcb0991SDimitry Andric 
3540b57cec5SDimitry Andric   return true;
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric static bool handleBranchExpect(BranchInst &BI) {
3580b57cec5SDimitry Andric   if (BI.isUnconditional())
3590b57cec5SDimitry Andric     return false;
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric   return handleBrSelExpect<BranchInst>(BI);
3620b57cec5SDimitry Andric }
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric static bool lowerExpectIntrinsic(Function &F) {
3650b57cec5SDimitry Andric   bool Changed = false;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   for (BasicBlock &BB : F) {
3680b57cec5SDimitry Andric     // Create "block_weights" metadata.
3690b57cec5SDimitry Andric     if (BranchInst *BI = dyn_cast<BranchInst>(BB.getTerminator())) {
3700b57cec5SDimitry Andric       if (handleBranchExpect(*BI))
3710b57cec5SDimitry Andric         ExpectIntrinsicsHandled++;
3720b57cec5SDimitry Andric     } else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB.getTerminator())) {
3730b57cec5SDimitry Andric       if (handleSwitchExpect(*SI))
3740b57cec5SDimitry Andric         ExpectIntrinsicsHandled++;
3750b57cec5SDimitry Andric     }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric     // Remove llvm.expect intrinsics. Iterate backwards in order
3780b57cec5SDimitry Andric     // to process select instructions before the intrinsic gets
3790b57cec5SDimitry Andric     // removed.
380349cc55cSDimitry Andric     for (Instruction &Inst : llvm::make_early_inc_range(llvm::reverse(BB))) {
381349cc55cSDimitry Andric       CallInst *CI = dyn_cast<CallInst>(&Inst);
3820b57cec5SDimitry Andric       if (!CI) {
383349cc55cSDimitry Andric         if (SelectInst *SI = dyn_cast<SelectInst>(&Inst)) {
3840b57cec5SDimitry Andric           if (handleBrSelExpect(*SI))
3850b57cec5SDimitry Andric             ExpectIntrinsicsHandled++;
3860b57cec5SDimitry Andric         }
3870b57cec5SDimitry Andric         continue;
3880b57cec5SDimitry Andric       }
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric       Function *Fn = CI->getCalledFunction();
3915ffd83dbSDimitry Andric       if (Fn && (Fn->getIntrinsicID() == Intrinsic::expect ||
3925ffd83dbSDimitry Andric                  Fn->getIntrinsicID() == Intrinsic::expect_with_probability)) {
3930b57cec5SDimitry Andric         // Before erasing the llvm.expect, walk backward to find
3940b57cec5SDimitry Andric         // phi that define llvm.expect's first arg, and
3950b57cec5SDimitry Andric         // infer branch probability:
3960b57cec5SDimitry Andric         handlePhiDef(CI);
3970b57cec5SDimitry Andric         Value *Exp = CI->getArgOperand(0);
3980b57cec5SDimitry Andric         CI->replaceAllUsesWith(Exp);
3990b57cec5SDimitry Andric         CI->eraseFromParent();
4000b57cec5SDimitry Andric         Changed = true;
4010b57cec5SDimitry Andric       }
4020b57cec5SDimitry Andric     }
4030b57cec5SDimitry Andric   }
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   return Changed;
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric PreservedAnalyses LowerExpectIntrinsicPass::run(Function &F,
4090b57cec5SDimitry Andric                                                 FunctionAnalysisManager &) {
4100b57cec5SDimitry Andric   if (lowerExpectIntrinsic(F))
4110b57cec5SDimitry Andric     return PreservedAnalyses::none();
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   return PreservedAnalyses::all();
4140b57cec5SDimitry Andric }
415