Page MenuHomePhabricator

D56074.id182861.diff
No OneTemporary

File Metadata

Created
Tue, Jun 18, 12:28 PM

D56074.id182861.diff

Index: llvm/trunk/include/llvm/Analysis/GuardUtils.h
===================================================================
--- llvm/trunk/include/llvm/Analysis/GuardUtils.h
+++ llvm/trunk/include/llvm/Analysis/GuardUtils.h
@@ -16,10 +16,14 @@
class User;
-/// Returns true iff \p U has semantics of a guard.
+/// Returns true iff \p U has semantics of a guard expressed in a form of call
+/// of llvm.experimental.guard intrinsic.
bool isGuard(const User *U);
+/// Returns true iff \p U has semantics of a guard expressed in a form of a
+/// widenable conditional branch to deopt block.
+bool isGuardAsWidenableBranch(const User *U);
+
} // llvm
#endif // LLVM_ANALYSIS_GUARDUTILS_H
-
Index: llvm/trunk/lib/Analysis/GuardUtils.cpp
===================================================================
--- llvm/trunk/lib/Analysis/GuardUtils.cpp
+++ llvm/trunk/lib/Analysis/GuardUtils.cpp
@@ -18,3 +18,30 @@
using namespace llvm::PatternMatch;
return match(U, m_Intrinsic<Intrinsic::experimental_guard>());
}
+
+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())
+ 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) {
+ if (match(&Insn, m_Intrinsic<Intrinsic::experimental_deoptimize>()))
+ return true;
+ if (Insn.mayHaveSideEffects())
+ return false;
+ }
+ return false;
+}

Event Timeline