summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/GuardUtils.cpp
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2019-01-22 09:36:22 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2019-01-22 09:36:22 +0000
commitbd374b27cc33567b0a0522ee511fc1ea9f0bb1df (patch)
tree90c1c6cf66a8be88b3e27b9b9d6d64f87372853f /llvm/lib/Analysis/GuardUtils.cpp
parentb88d6fd7b8c0f40a919e463b9b8c9193efbc5eaa (diff)
downloadbcm5719-llvm-bd374b27cc33567b0a0522ee511fc1ea9f0bb1df.tar.gz
bcm5719-llvm-bd374b27cc33567b0a0522ee511fc1ea9f0bb1df.zip
[NFC] Add detector for guards expressed as branch by widenable conditions
This patch adds a function to detect guards expressed in explicit control flow form as branch by `and` with widenable condition intrinsic call: %wc = call i1 @llvm.experimental.widenable.condition() %guard_cond = and i1, %some_cond, %wc br i1 %guard_cond, label %guarded, label %deopt deopt: <maybe some non-side-effecting instructions> deoptimize() This form can be used as alternative to implicit control flow guard representation expressed by `experimental_guard` intrinsic. Differential Revision: https://reviews.llvm.org/D56074 Reviewed By: reames llvm-svn: 351791
Diffstat (limited to 'llvm/lib/Analysis/GuardUtils.cpp')
-rw-r--r--llvm/lib/Analysis/GuardUtils.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/GuardUtils.cpp b/llvm/lib/Analysis/GuardUtils.cpp
index 2cee473e289..36ae954ed8b 100644
--- a/llvm/lib/Analysis/GuardUtils.cpp
+++ b/llvm/lib/Analysis/GuardUtils.cpp
@@ -18,3 +18,30 @@ bool llvm::isGuard(const User *U) {
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;
+}
OpenPOWER on IntegriCloud