From: Max Kazantsev Date: Tue, 22 Jan 2019 11:21:32 +0000 (+0000) Subject: [NFC] Add function to parse widenable conditional branches X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b92e756f41e8c37bbbedca05089c04723606d8b8;p=llvm [NFC] Add function to parse widenable conditional branches git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351803 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/GuardUtils.h b/include/llvm/Analysis/GuardUtils.h index 62ae09a4f8f..41e7b7c06c7 100644 --- a/include/llvm/Analysis/GuardUtils.h +++ b/include/llvm/Analysis/GuardUtils.h @@ -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 diff --git a/lib/Analysis/GuardUtils.cpp b/lib/Analysis/GuardUtils.cpp index 36ae954ed8b..c099ee8e41c 100644 --- a/lib/Analysis/GuardUtils.cpp +++ b/lib/Analysis/GuardUtils.cpp @@ -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(U); - - // We are looking for the following pattern: - // br i1 %cond & widenable_condition(), label %guarded, label %deopt - // deopt: - // - // 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()))) - 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())) 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)); +}