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