[llvm] 7a0debe - [NFC][LoopPredication] Extract guard parsing to GuardUtils
Aleksandr Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 10 01:01:16 PDT 2023
Author: Aleksandr Popov
Date: 2023-08-10T10:00:42+02:00
New Revision: 7a0debebde5de629b091c0c099d2ef89131cea04
URL: https://github.com/llvm/llvm-project/commit/7a0debebde5de629b091c0c099d2ef89131cea04
DIFF: https://github.com/llvm/llvm-project/commit/7a0debebde5de629b091c0c099d2ef89131cea04.diff
LOG: [NFC][LoopPredication] Extract guard parsing to GuardUtils
Extract logic of parsing guards and widenable branches in order to reuse
it in the GuardWidening
Reviewed By: anna
Differential Revision: https://reviews.llvm.org/D157276
Added:
Modified:
llvm/include/llvm/Analysis/GuardUtils.h
llvm/lib/Analysis/GuardUtils.cpp
llvm/lib/Transforms/Scalar/LoopPredication.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/GuardUtils.h b/llvm/include/llvm/Analysis/GuardUtils.h
index b83211535ec234..3ac6c8e6dd8f15 100644
--- a/llvm/include/llvm/Analysis/GuardUtils.h
+++ b/llvm/include/llvm/Analysis/GuardUtils.h
@@ -18,11 +18,16 @@ class BasicBlock;
class Use;
class User;
class Value;
+template <typename T> class SmallVectorImpl;
/// 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 V has semantics of llvm.experimental.widenable.condition
+/// call
+bool isWidenableCondition(const Value *V);
+
/// Returns true iff \p U is a widenable branch (that is, parseWidenableBranch
/// returns true).
bool isWidenableBranch(const User *U);
@@ -48,7 +53,13 @@ bool parseWidenableBranch(const User *U, Value *&Condition,
/// modified. Unlike previous version, Condition is optional and may be null.
bool parseWidenableBranch(User *U, Use *&Cond, Use *&WC, BasicBlock *&IfTrueBB,
BasicBlock *&IfFalseBB);
-
+
+// The guard condition is expected to be in form of:
+// cond1 && cond2 && cond3 ...
+// or in case of widenable branch:
+// cond1 && cond2 && cond3 && widenable_contidion ...
+// Method collects the list of checks, but skips widenable_condition.
+void parseWidenableGuard(const User *U, llvm::SmallVectorImpl<Value *> &Checks);
} // llvm
#endif // LLVM_ANALYSIS_GUARDUTILS_H
diff --git a/llvm/lib/Analysis/GuardUtils.cpp b/llvm/lib/Analysis/GuardUtils.cpp
index 40b898e96f3bba..1239ee693d3ab3 100644
--- a/llvm/lib/Analysis/GuardUtils.cpp
+++ b/llvm/lib/Analysis/GuardUtils.cpp
@@ -19,6 +19,10 @@ bool llvm::isGuard(const User *U) {
return match(U, m_Intrinsic<Intrinsic::experimental_guard>());
}
+bool llvm::isWidenableCondition(const Value *V) {
+ return match(V, m_Intrinsic<Intrinsic::experimental_widenable_condition>());
+}
+
bool llvm::isWidenableBranch(const User *U) {
Value *Condition, *WidenableCondition;
BasicBlock *GuardedBB, *DeoptBB;
@@ -111,3 +115,34 @@ bool llvm::parseWidenableBranch(User *U, Use *&C,Use *&WC,
}
return false;
}
+
+template <typename CallbackType>
+static void parseCondition(Value *Condition, CallbackType Callback) {
+ SmallVector<Value *, 4> Worklist(1, Condition);
+ SmallPtrSet<Value *, 4> Visited;
+ Visited.insert(Condition);
+ do {
+ Value *Check = Worklist.pop_back_val();
+ Value *LHS, *RHS;
+ if (match(Check, m_And(m_Value(LHS), m_Value(RHS)))) {
+ if (Visited.insert(LHS).second)
+ Worklist.push_back(LHS);
+ if (Visited.insert(RHS).second)
+ Worklist.push_back(RHS);
+ continue;
+ }
+ Callback(Check);
+ } while (!Worklist.empty());
+}
+
+void llvm::parseWidenableGuard(const User *U,
+ llvm::SmallVectorImpl<Value *> &Checks) {
+ assert((isGuard(U) || isWidenableBranch(U)) && "Should be");
+ Value *Condition = isGuard(U) ? cast<IntrinsicInst>(U)->getArgOperand(0)
+ : cast<BranchInst>(U)->getCondition();
+
+ parseCondition(Condition, [&](Value *Check) {
+ if (!isWidenableCondition(Check))
+ Checks.push_back(Check);
+ });
+}
diff --git a/llvm/lib/Transforms/Scalar/LoopPredication.cpp b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
index 12852ae5c4608c..79a3da9020e2e2 100644
--- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
@@ -307,8 +307,8 @@ class LoopPredication {
widenICmpRangeCheckDecrementingLoop(LoopICmp LatchCheck, LoopICmp RangeCheck,
SCEVExpander &Expander,
Instruction *Guard);
- unsigned collectChecks(SmallVectorImpl<Value *> &Checks, Value *Condition,
- SCEVExpander &Expander, Instruction *Guard);
+ unsigned widenChecks(SmallVectorImpl<Value *> &Checks, SCEVExpander &Expander,
+ Instruction *Guard);
bool widenGuardConditions(IntrinsicInst *II, SCEVExpander &Expander);
bool widenWidenableBranchGuardConditions(BranchInst *Guard, SCEVExpander &Expander);
// If the loop always exits through another block in the loop, we should not
@@ -754,57 +754,16 @@ LoopPredication::widenICmpRangeCheck(ICmpInst *ICI, SCEVExpander &Expander,
}
}
-unsigned LoopPredication::collectChecks(SmallVectorImpl<Value *> &Checks,
- Value *Condition,
- SCEVExpander &Expander,
- Instruction *Guard) {
+unsigned LoopPredication::widenChecks(SmallVectorImpl<Value *> &Checks,
+ SCEVExpander &Expander,
+ Instruction *Guard) {
unsigned NumWidened = 0;
- // The guard condition is expected to be in form of:
- // cond1 && cond2 && cond3 ...
- // Iterate over subconditions looking for icmp conditions which can be
- // widened across loop iterations. Widening these conditions remember the
- // resulting list of subconditions in Checks vector.
- SmallVector<Value *, 4> Worklist(1, Condition);
- SmallPtrSet<Value *, 4> Visited;
- Visited.insert(Condition);
- Value *WideableCond = nullptr;
- do {
- Value *Condition = Worklist.pop_back_val();
- Value *LHS, *RHS;
- using namespace llvm::PatternMatch;
- if (match(Condition, m_And(m_Value(LHS), m_Value(RHS)))) {
- if (Visited.insert(LHS).second)
- Worklist.push_back(LHS);
- if (Visited.insert(RHS).second)
- Worklist.push_back(RHS);
- continue;
- }
-
- if (match(Condition,
- m_Intrinsic<Intrinsic::experimental_widenable_condition>())) {
- // Pick any, we don't care which
- WideableCond = Condition;
- continue;
- }
-
- if (ICmpInst *ICI = dyn_cast<ICmpInst>(Condition)) {
- if (auto NewRangeCheck = widenICmpRangeCheck(ICI, Expander,
- Guard)) {
- Checks.push_back(*NewRangeCheck);
+ for (auto &Check : Checks)
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(Check))
+ if (auto NewRangeCheck = widenICmpRangeCheck(ICI, Expander, Guard)) {
NumWidened++;
- continue;
+ Check = *NewRangeCheck;
}
- }
-
- // Save the condition as is if we can't widen it
- Checks.push_back(Condition);
- } while (!Worklist.empty());
- // At the moment, our matching logic for wideable conditions implicitly
- // assumes we preserve the form: (br (and Cond, WC())). FIXME
- // Note that if there were multiple calls to wideable condition in the
- // traversal, we only need to keep one, and which one is arbitrary.
- if (WideableCond)
- Checks.push_back(WideableCond);
return NumWidened;
}
@@ -815,8 +774,8 @@ bool LoopPredication::widenGuardConditions(IntrinsicInst *Guard,
TotalConsidered++;
SmallVector<Value *, 4> Checks;
- unsigned NumWidened = collectChecks(Checks, Guard->getOperand(0), Expander,
- Guard);
+ parseWidenableGuard(Guard, Checks);
+ unsigned NumWidened = widenChecks(Checks, Expander, Guard);
if (NumWidened == 0)
return false;
@@ -851,8 +810,11 @@ bool LoopPredication::widenWidenableBranchGuardConditions(
TotalConsidered++;
SmallVector<Value *, 4> Checks;
- unsigned NumWidened = collectChecks(Checks, BI->getCondition(),
- Expander, BI);
+ parseWidenableGuard(BI, Checks);
+ // At the moment, our matching logic for wideable conditions implicitly
+ // assumes we preserve the form: (br (and Cond, WC())). FIXME
+ Checks.push_back(WC);
+ unsigned NumWidened = widenChecks(Checks, Expander, BI);
if (NumWidened == 0)
return false;
More information about the llvm-commits
mailing list