[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