LLVM  12.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 analyzes related to guards and their
9 // conditions.
10 //===----------------------------------------------------------------------===//
11 
13 #include "llvm/IR/PatternMatch.h"
14 
15 using namespace llvm;
16 using namespace llvm::PatternMatch;
17 
18 bool llvm::isGuard(const User *U) {
19  return match(U, m_Intrinsic<Intrinsic::experimental_guard>());
20 }
21 
22 bool llvm::isWidenableBranch(const User *U) {
23  Value *Condition, *WidenableCondition;
24  BasicBlock *GuardedBB, *DeoptBB;
25  return parseWidenableBranch(U, Condition, WidenableCondition, GuardedBB,
26  DeoptBB);
27 }
28 
30  Value *Condition, *WidenableCondition;
31  BasicBlock *GuardedBB, *DeoptBB;
32  if (!parseWidenableBranch(U, Condition, WidenableCondition, GuardedBB,
33  DeoptBB))
34  return false;
35  for (auto &Insn : *DeoptBB) {
36  if (match(&Insn, m_Intrinsic<Intrinsic::experimental_deoptimize>()))
37  return true;
38  if (Insn.mayHaveSideEffects())
39  return false;
40  }
41  return false;
42 }
43 
44 bool llvm::parseWidenableBranch(const User *U, Value *&Condition,
45  Value *&WidenableCondition,
46  BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB) {
47 
48  Use *C, *WC;
49  if (parseWidenableBranch(const_cast<User*>(U), C, WC, IfTrueBB, IfFalseBB)) {
50  if (C)
51  Condition = C->get();
52  else
53  Condition = ConstantInt::getTrue(IfTrueBB->getContext());
54  WidenableCondition = WC->get();
55  return true;
56  }
57  return false;
58 }
59 
61  BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB) {
62 
63  auto *BI = dyn_cast<BranchInst>(U);
64  if (!BI || !BI->isConditional())
65  return false;
66  auto *Cond = BI->getCondition();
67  if (!Cond->hasOneUse())
68  return false;
69 
70  IfTrueBB = BI->getSuccessor(0);
71  IfFalseBB = BI->getSuccessor(1);
72 
73  if (match(Cond, m_Intrinsic<Intrinsic::experimental_widenable_condition>())) {
74  WC = &BI->getOperandUse(0);
75  C = nullptr;
76  return true;
77  }
78 
79  // Check for two cases:
80  // 1) br (i1 (and A, WC())), label %IfTrue, label %IfFalse
81  // 2) br (i1 (and WC(), B)), label %IfTrue, label %IfFalse
82  // We do not check for more generalized and trees as we should canonicalize
83  // to the form above in instcombine. (TODO)
84  Value *A, *B;
85  if (!match(Cond, m_And(m_Value(A), m_Value(B))))
86  return false;
87  auto *And = dyn_cast<Instruction>(Cond);
88  if (!And)
89  // Could be a constexpr
90  return false;
91 
92  if (match(A, m_Intrinsic<Intrinsic::experimental_widenable_condition>()) &&
93  A->hasOneUse()) {
94  WC = &And->getOperandUse(0);
95  C = &And->getOperandUse(1);
96  return true;
97  }
98 
99  if (match(B, m_Intrinsic<Intrinsic::experimental_widenable_condition>()) &&
100  B->hasOneUse()) {
101  WC = &And->getOperandUse(1);
102  C = &And->getOperandUse(0);
103  return true;
104  }
105  return false;
106 }
bool isWidenableBranch(const User *U)
Returns true iff U is a widenable branch (that is, parseWidenableBranch returns true).
Definition: GuardUtils.cpp:22
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
uint64_t CallInst * C
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Definition: PatternMatch.h:76
LLVM_NODISCARD std::enable_if_t< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition: Casting.h:334
This class represents lattice values for constants.
Definition: AllocatorList.h:23
LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:32
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:49
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
Conditional or Unconditional Branch instruction.
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
static ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:794
bool isGuard(const User *U)
Returns true iff U has semantics of a guard expressed in a form of call of llvm.experimental.guard intrinsic.
Definition: GuardUtils.cpp:18
SmallVector< MachineOperand, 4 > Cond
LLVM Value Representation.
Definition: Value.h:75
bool isGuardAsWidenableBranch(const User *U)
Returns true iff U has semantics of a guard expressed in a form of a widenable conditional branch to ...
Definition: GuardUtils.cpp:29
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition: Value.h:433