15820d6280375716df3f18f39966eb2c595befabeChandler Carruth//===- LowerExpectIntrinsic.cpp - Lower expect intrinsic ------------------===// 25820d6280375716df3f18f39966eb2c595befabeChandler Carruth// 35820d6280375716df3f18f39966eb2c595befabeChandler Carruth// The LLVM Compiler Infrastructure 45820d6280375716df3f18f39966eb2c595befabeChandler Carruth// 55820d6280375716df3f18f39966eb2c595befabeChandler Carruth// This file is distributed under the University of Illinois Open Source 65820d6280375716df3f18f39966eb2c595befabeChandler Carruth// License. See LICENSE.TXT for details. 75820d6280375716df3f18f39966eb2c595befabeChandler Carruth// 85820d6280375716df3f18f39966eb2c595befabeChandler Carruth//===----------------------------------------------------------------------===// 95820d6280375716df3f18f39966eb2c595befabeChandler Carruth// 105820d6280375716df3f18f39966eb2c595befabeChandler Carruth// This pass lowers the 'expect' intrinsic to LLVM metadata. 115820d6280375716df3f18f39966eb2c595befabeChandler Carruth// 125820d6280375716df3f18f39966eb2c595befabeChandler Carruth//===----------------------------------------------------------------------===// 135820d6280375716df3f18f39966eb2c595befabeChandler Carruth 14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" 15ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ADT/SmallVector.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/BasicBlock.h" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h" 220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/MDBuilder.h" 240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Metadata.h" 259da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak#include "llvm/Pass.h" 269da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak#include "llvm/Support/CommandLine.h" 279da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak#include "llvm/Support/Debug.h" 28ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Transforms/Scalar.h" 299da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 309da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszakusing namespace llvm; 319da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "lower-expect-intrinsic" 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 34ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesSTATISTIC(ExpectIntrinsicsHandled, 35ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "Number of 'expect' intrinsic instructions handled"); 369da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 379da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszakstatic cl::opt<uint32_t> 389da9934e27dfb48de77b80a3e20ed2d869b52024Jakub StaszakLikelyBranchWeight("likely-branch-weight", cl::Hidden, cl::init(64), 399da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak cl::desc("Weight of the branch likely to be taken (default = 64)")); 409da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszakstatic cl::opt<uint32_t> 419da9934e27dfb48de77b80a3e20ed2d869b52024Jakub StaszakUnlikelyBranchWeight("unlikely-branch-weight", cl::Hidden, cl::init(4), 429da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak cl::desc("Weight of the branch unlikely to be taken (default = 4)")); 439da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 44ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic bool handleSwitchExpect(SwitchInst &SI) { 45ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CallInst *CI = dyn_cast<CallInst>(SI.getCondition()); 469da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak if (!CI) 479da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return false; 489da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 499da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak Function *Fn = CI->getCalledFunction(); 509da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) 519da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return false; 529da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 539da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak Value *ArgValue = CI->getArgOperand(0); 549da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 559da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak if (!ExpectedValue) 569da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return false; 579da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SwitchInst::CaseIt Case = SI.findCaseValue(ExpectedValue); 59ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned n = SI.getNumCases(); // +1 for default case. 60ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<uint32_t, 16> Weights(n + 1, UnlikelyBranchWeight); 619da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Case == SI.case_default()) 63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Weights[0] = LikelyBranchWeight; 64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Weights[Case.getCaseIndex() + 1] = LikelyBranchWeight; 669da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SI.setMetadata(LLVMContext::MD_prof, 68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MDBuilder(CI->getContext()).createBranchWeights(Weights)); 699da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SI.setCondition(ArgValue); 719da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return true; 729da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak} 739da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 74ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic bool handleBranchExpect(BranchInst &BI) { 75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (BI.isUnconditional()) 769da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return false; 779da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 789da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak // Handle non-optimized IR code like: 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1) 809da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak // %tobool = icmp ne i64 %expval, 0 819da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak // br i1 %tobool, label %if.then, label %if.end 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Or the following simpler case: 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1) 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // br i1 %expval, label %if.then, label %if.end 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CallInst *CI; 889da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ICmpInst *CmpI = dyn_cast<ICmpInst>(BI.getCondition()); 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!CmpI) { 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CI = dyn_cast<CallInst>(BI.getCondition()); 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CmpI->getPredicate() != CmpInst::ICMP_NE) 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CI = dyn_cast<CallInst>(CmpI->getOperand(0)); 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 979da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 989da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak if (!CI) 999da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return false; 1009da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 1019da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak Function *Fn = CI->getCalledFunction(); 1029da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) 1039da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return false; 1049da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 1059da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak Value *ArgValue = CI->getArgOperand(0); 1069da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 1079da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak if (!ExpectedValue) 1089da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return false; 1099da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 110937338cf64350a7d05d0c956dc8e8564e959cb7bBenjamin Kramer MDBuilder MDB(CI->getContext()); 111937338cf64350a7d05d0c956dc8e8564e959cb7bBenjamin Kramer MDNode *Node; 1129da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 1139da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak // If expect value is equal to 1 it means that we are more likely to take 1149da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak // branch 0, in other case more likely is branch 1. 115937338cf64350a7d05d0c956dc8e8564e959cb7bBenjamin Kramer if (ExpectedValue->isOne()) 116937338cf64350a7d05d0c956dc8e8564e959cb7bBenjamin Kramer Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight); 117937338cf64350a7d05d0c956dc8e8564e959cb7bBenjamin Kramer else 118937338cf64350a7d05d0c956dc8e8564e959cb7bBenjamin Kramer Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); 1199da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BI.setMetadata(LLVMContext::MD_prof, Node); 1219da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CmpI) 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CmpI->setOperand(0, ArgValue); 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BI.setCondition(ArgValue); 1269da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return true; 1279da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak} 1289da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic bool lowerExpectIntrinsic(Function &F) { 130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool Changed = false; 1319da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (BasicBlock &BB : F) { 1339da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak // Create "block_weights" metadata. 134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (BranchInst *BI = dyn_cast<BranchInst>(BB.getTerminator())) { 135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (handleBranchExpect(*BI)) 136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExpectIntrinsicsHandled++; 137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB.getTerminator())) { 138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (handleSwitchExpect(*SI)) 139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ExpectIntrinsicsHandled++; 1409da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak } 1419da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 142cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Remove llvm.expect intrinsics. 143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (BasicBlock::iterator BI = BB.begin(), BE = BB.end(); BI != BE;) { 1449da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak CallInst *CI = dyn_cast<CallInst>(BI++); 1459da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak if (!CI) 1469da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak continue; 1479da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 1489da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak Function *Fn = CI->getCalledFunction(); 149447c40c4028f1563826ea75f47fd3ec48c7a74adJakub Staszak if (Fn && Fn->getIntrinsicID() == Intrinsic::expect) { 150447c40c4028f1563826ea75f47fd3ec48c7a74adJakub Staszak Value *Exp = CI->getArgOperand(0); 151447c40c4028f1563826ea75f47fd3ec48c7a74adJakub Staszak CI->replaceAllUsesWith(Exp); 1529da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak CI->eraseFromParent(); 153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Changed = true; 154447c40c4028f1563826ea75f47fd3ec48c7a74adJakub Staszak } 1559da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak } 1569da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak } 1579da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Changed; 1599da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak} 1609da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 161ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesPreservedAnalyses LowerExpectIntrinsicPass::run(Function &F) { 162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (lowerExpectIntrinsic(F)) 163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return PreservedAnalyses::none(); 164ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 165ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return PreservedAnalyses::all(); 166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace { 169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief Legacy pass for lowering expect intrinsics out of the IR. 170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// When this pass is run over a function it uses expect intrinsics which feed 172ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// branches and switches to provide branch weight metadata for those 173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// terminators. It then removes the expect intrinsics from the IR so the rest 174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// of the optimizer can ignore them. 175ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass LowerExpectIntrinsic : public FunctionPass { 176ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 177ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static char ID; 178ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LowerExpectIntrinsic() : FunctionPass(ID) { 179ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines initializeLowerExpectIntrinsicPass(*PassRegistry::getPassRegistry()); 180ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 181ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool runOnFunction(Function &F) override { return lowerExpectIntrinsic(F); } 183ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 184ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 1859da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 1869da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszakchar LowerExpectIntrinsic::ID = 0; 187ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS(LowerExpectIntrinsic, "lower-expect", 188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "Lower 'expect' Intrinsics", false, false) 1899da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 1909da9934e27dfb48de77b80a3e20ed2d869b52024Jakub StaszakFunctionPass *llvm::createLowerExpectIntrinsicPass() { 1919da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak return new LowerExpectIntrinsic(); 1929da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak} 193