mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-23 12:24:34 +00:00
[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
This commit is contained in:
parent
ac2839a57d
commit
75db383edd
@ -16,10 +16,14 @@ namespace llvm {
|
||||
|
||||
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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user