]> granicus.if.org Git - llvm/commitdiff
[NFC] Add function to parse widenable conditional branches
authorMax Kazantsev <max.kazantsev@azul.com>
Tue, 22 Jan 2019 11:21:32 +0000 (11:21 +0000)
committerMax Kazantsev <max.kazantsev@azul.com>
Tue, 22 Jan 2019 11:21:32 +0000 (11:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351803 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/GuardUtils.h
lib/Analysis/GuardUtils.cpp

index 62ae09a4f8fd1ba68ca0723d682b7c7f92055d3b..41e7b7c06c7501b17d4fd2ca0d2b3165dbae6da3 100644 (file)
@@ -14,7 +14,9 @@
 
 namespace llvm {
 
+class BasicBlock;
 class User;
+class Value;
 
 /// Returns true iff \p U has semantics of a guard expressed in a form of call
 /// of llvm.experimental.guard intrinsic.
@@ -24,6 +26,19 @@ bool isGuard(const User *U);
 /// widenable conditional branch to deopt block.
 bool isGuardAsWidenableBranch(const User *U);
 
+/// If U is widenable branch looking like:
+///   %cond = ...
+///   %wc = call i1 @llvm.experimental.widenable.condition()
+///   %branch_cond = and i1 %cond, %wc
+///   br i1 %branch_cond, label %if_true_bb, label %if_false_bb ; <--- U
+/// The function returns true, and the values %cond and %wc and blocks
+/// %if_true_bb, if_false_bb are returned in
+/// the parameters (Condition, WidenableCondition, IfTrueBB and IfFalseFF)
+/// respectively. If \p U does not match this pattern, return false.
+bool parseWidenableBranch(const User *U, Value *&Condition,
+                          Value *&WidenableCondition, BasicBlock *&IfTrueBB,
+                          BasicBlock *&IfFalseBB);
+
 } // llvm
 
 #endif // LLVM_ANALYSIS_GUARDUTILS_H
index 36ae954ed8b6c3f0aa6efba8e9f301721f4b0d76..c099ee8e41c66efcfd9a4a380969d519a968adb4 100644 (file)
@@ -20,24 +20,13 @@ bool llvm::isGuard(const User *U) {
 }
 
 bool llvm::isGuardAsWidenableBranch(const User *U) {
-  using namespace llvm::PatternMatch;
-  const BranchInst *BI = dyn_cast<BranchInst>(U);
-
-  // We are looking for the following pattern:
-  //   br i1 %cond & widenable_condition(), label %guarded, label %deopt
-  // deopt:
-  //   <non-side-effecting instructions>
-  //   deoptimize()
-  if (!BI || !BI->isConditional())
+  Value *Condition, *WidenableCondition;
+  BasicBlock *GuardedBB, *DeoptBB;
+  if (!parseWidenableBranch(U, Condition, WidenableCondition, GuardedBB,
+                            DeoptBB))
     return false;
-
-  if (!match(BI->getCondition(),
-             m_And(m_Value(),
-                   m_Intrinsic<Intrinsic::experimental_widenable_condition>())))
-    return false;
-
-  const BasicBlock *DeoptBlock = BI->getSuccessor(1);
-  for (auto &Insn : *DeoptBlock) {
+  using namespace llvm::PatternMatch;
+  for (auto &Insn : *DeoptBB) {
     if (match(&Insn, m_Intrinsic<Intrinsic::experimental_deoptimize>()))
       return true;
     if (Insn.mayHaveSideEffects())
@@ -45,3 +34,11 @@ bool llvm::isGuardAsWidenableBranch(const User *U) {
   }
   return false;
 }
+
+bool llvm::parseWidenableBranch(const User *U, Value *&Condition,
+                                Value *&WidenableCondition,
+                                BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB) {
+  using namespace llvm::PatternMatch;
+  return match(U, m_Br(m_And(m_Value(Condition), m_Value(WidenableCondition)),
+                       IfTrueBB, IfFalseBB));
+}