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