LLVM  14.0.0git
GuardUtils.cpp
Go to the documentation of this file.
1 //===-- GuardUtils.cpp - Utils for work with guards -------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // Utils that are used to perform transformations related to guards and their
9 // conditions.
10 //===----------------------------------------------------------------------===//
11 
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/IRBuilder.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/MDBuilder.h"
18 #include "llvm/IR/PatternMatch.h"
21 
22 using namespace llvm;
23 using namespace llvm::PatternMatch;
24 
26  "guards-predicate-pass-branch-weight", cl::Hidden, cl::init(1 << 20),
27  cl::desc("The probability of a guard failing is assumed to be the "
28  "reciprocal of this value (default = 1 << 20)"));
29 
31  CallInst *Guard, bool UseWC) {
34 
35  auto *CheckBB = Guard->getParent();
36  auto *DeoptBlockTerm =
37  SplitBlockAndInsertIfThen(Guard->getArgOperand(0), Guard, true);
38 
39  auto *CheckBI = cast<BranchInst>(CheckBB->getTerminator());
40 
41  // SplitBlockAndInsertIfThen inserts control flow that branches to
42  // DeoptBlockTerm if the condition is true. We want the opposite.
43  CheckBI->swapSuccessors();
44 
45  CheckBI->getSuccessor(0)->setName("guarded");
46  CheckBI->getSuccessor(1)->setName("deopt");
47 
48  if (auto *MD = Guard->getMetadata(LLVMContext::MD_make_implicit))
49  CheckBI->setMetadata(LLVMContext::MD_make_implicit, MD);
50 
51  MDBuilder MDB(Guard->getContext());
52  CheckBI->setMetadata(LLVMContext::MD_prof,
54 
55  IRBuilder<> B(DeoptBlockTerm);
56  auto *DeoptCall = B.CreateCall(DeoptIntrinsic, Args, {DeoptOB}, "");
57 
58  if (DeoptIntrinsic->getReturnType()->isVoidTy()) {
59  B.CreateRetVoid();
60  } else {
61  DeoptCall->setName("deoptcall");
62  B.CreateRet(DeoptCall);
63  }
64 
65  DeoptCall->setCallingConv(Guard->getCallingConv());
66  DeoptBlockTerm->eraseFromParent();
67 
68  if (UseWC) {
69  // We want the guard to be expressed as explicit control flow, but still be
70  // widenable. For that, we add Widenable Condition intrinsic call to the
71  // guard's condition.
72  IRBuilder<> B(CheckBI);
73  auto *WC = B.CreateIntrinsic(Intrinsic::experimental_widenable_condition,
74  {}, {}, nullptr, "widenable_cond");
75  CheckBI->setCondition(B.CreateAnd(CheckBI->getCondition(), WC,
76  "exiplicit_guard_cond"));
77  assert(isWidenableBranch(CheckBI) && "sanity check");
78  }
79 }
80 
81 
82 void llvm::widenWidenableBranch(BranchInst *WidenableBR, Value *NewCond) {
83  assert(isWidenableBranch(WidenableBR) && "precondition");
84 
85  // The tempting trivially option is to produce something like this:
86  // br (and oldcond, newcond) where oldcond is assumed to contain a widenable
87  // condition, but that doesn't match the pattern parseWidenableBranch expects
88  // so we have to be more sophisticated.
89 
90  Use *C, *WC;
91  BasicBlock *IfTrueBB, *IfFalseBB;
92  parseWidenableBranch(WidenableBR, C, WC, IfTrueBB, IfFalseBB);
93  if (!C) {
94  // br (wc()), ... form
95  IRBuilder<> B(WidenableBR);
96  WidenableBR->setCondition(B.CreateAnd(NewCond, WC->get()));
97  } else {
98  // br (wc & C), ... form
99  IRBuilder<> B(WidenableBR);
100  C->set(B.CreateAnd(NewCond, C->get()));
101  Instruction *WCAnd = cast<Instruction>(WidenableBR->getCondition());
102  // Condition is only guaranteed to dominate branch
103  WCAnd->moveBefore(WidenableBR);
104  }
105  assert(isWidenableBranch(WidenableBR) && "preserve widenabiliy");
106 }
107 
108 void llvm::setWidenableBranchCond(BranchInst *WidenableBR, Value *NewCond) {
109  assert(isWidenableBranch(WidenableBR) && "precondition");
110 
111  Use *C, *WC;
112  BasicBlock *IfTrueBB, *IfFalseBB;
113  parseWidenableBranch(WidenableBR, C, WC, IfTrueBB, IfFalseBB);
114  if (!C) {
115  // br (wc()), ... form
116  IRBuilder<> B(WidenableBR);
117  WidenableBR->setCondition(B.CreateAnd(NewCond, WC->get()));
118  } else {
119  // br (wc & C), ... form
120  Instruction *WCAnd = cast<Instruction>(WidenableBR->getCondition());
121  // Condition is only guaranteed to dominate branch
122  WCAnd->moveBefore(WidenableBR);
123  C->set(NewCond);
124  }
125  assert(isWidenableBranch(WidenableBR) && "preserve widenabiliy");
126 }
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::makeGuardControlFlowExplicit
void makeGuardControlFlowExplicit(Function *DeoptIntrinsic, CallInst *Guard, bool UseWC)
Splits control flow at point of Guard, replacing it with explicit branch by the condition of guard's ...
Definition: GuardUtils.cpp:30
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:266
llvm::CallBase::getOperandBundle
Optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Definition: InstrTypes.h:1987
llvm::Function
Definition: Function.h:61
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::IRBuilder<>
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::OperandBundleDefT
A container for an operand bundle being viewed as a set of values rather than a set of uses.
Definition: InstrTypes.h:1114
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
CommandLine.h
llvm::setWidenableBranchCond
void setWidenableBranchCond(BranchInst *WidenableBR, Value *Cond)
Given a branch we know is widenable (defined per Analysis/GuardUtils.h), set it's condition such that...
Definition: GuardUtils.cpp:108
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
GuardUtils.h
llvm::MDBuilder::createBranchWeights
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
Definition: MDBuilder.cpp:37
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::Instruction
Definition: Instruction.h:45
llvm::BranchInst::setCondition
void setCondition(Value *V)
Definition: Instructions.h:3154
MDBuilder.h
PatternMatch.h
llvm::CallBase::getCallingConv
CallingConv::ID getCallingConv() const
Definition: InstrTypes.h:1449
llvm::Instruction::getMetadata
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:282
llvm::BranchInst::getCondition
Value * getCondition() const
Definition: Instructions.h:3149
llvm::cl::opt
Definition: CommandLine.h:1434
llvm::LLVMContext::OB_deopt
@ OB_deopt
Definition: LLVMContext.h:90
llvm::Function::getReturnType
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:181
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::widenWidenableBranch
void widenWidenableBranch(BranchInst *WidenableBR, Value *NewCond)
Given a branch we know is widenable (defined per Analysis/GuardUtils.h), widen it such that condition...
Definition: GuardUtils.cpp:82
llvm::Type::isVoidTy
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:138
llvm::parseWidenableBranch
bool parseWidenableBranch(const User *U, Value *&Condition, Value *&WidenableCondition, BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB)
If U is widenable branch looking like: cond = ...
Definition: GuardUtils.cpp:44
llvm::isWidenableBranch
bool isWidenableBranch(const User *U)
Returns true iff U is a widenable branch (that is, parseWidenableBranch returns true).
Definition: GuardUtils.cpp:22
PredicatePassBranchWeight
static cl::opt< uint32_t > PredicatePassBranchWeight("guards-predicate-pass-branch-weight", cl::Hidden, cl::init(1<< 20), cl::desc("The probability of a guard failing is assumed to be the " "reciprocal of this value (default = 1 << 20)"))
llvm::Value::getContext
LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:990
Function.h
GuardUtils.h
llvm::MDBuilder
Definition: MDBuilder.h:35
Instructions.h
llvm::CallBase::getArgOperand
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1338
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:94
llvm::PatternMatch
Definition: PatternMatch.h:47
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1475
llvm::SplitBlockAndInsertIfThen
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights, DominatorTree *DT, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
Definition: BasicBlockUtils.cpp:1418
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::cl::desc
Definition: CommandLine.h:414
llvm::BranchInst
Conditional or Unconditional Branch instruction.
Definition: Instructions.h:3068
BasicBlockUtils.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::CallBase::args
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1319
llvm::Instruction::moveBefore
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
Definition: Instruction.cpp:97
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44