[PATCH] D111903: [SCEV] Use defining scope to bound backwards predicate search [mostly-nfc]

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 15 11:33:08 PDT 2021


reames created this revision.
reames added reviewers: mkazantsev, nikic.
Herald added subscribers: bollu, hiraditya, mcrosier.
reames requested review of this revision.
Herald added a project: LLVM.

The basic idea here is that if we have an expression, we can't find a predicate which proves facts about that expression outside the region in which that expression is defined.  We can find facts about sub-expressions, but the current logic doesn't let us leverage those.  (Note that applyLoopGuards does build facts about sub-expressions and then lazily apply them, so we can't do the same there.  In theory at least.)

The one exception is that a trivially unreachable block currently implies all conditions and we loose that.  I'm honestly not sure how interesting that is given simplify-cfg and friends will rip the code away wholesale.

The motivation here is to improve compile time.  @nikic Do you see any positive impact from this?  If not, I'll abandon as the complexity is not worth it on it's own.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111903

Files:
  llvm/lib/Analysis/ScalarEvolution.cpp
  llvm/test/Transforms/IndVarSimplify/trivial-guard.ll


Index: llvm/test/Transforms/IndVarSimplify/trivial-guard.ll
===================================================================
--- llvm/test/Transforms/IndVarSimplify/trivial-guard.ll
+++ llvm/test/Transforms/IndVarSimplify/trivial-guard.ll
@@ -21,8 +21,11 @@
 ; CHECK-NEXT:    [[LOOP_COND_1:%.*]] = call i1 @cond()
 ; CHECK-NEXT:    br i1 [[LOOP_COND_1]], label [[LOOP_1]], label [[EXIT_LOOPEXIT:%.*]]
 ; CHECK:       loop.2:
-; CHECK-NEXT:    br i1 true, label [[GUARDED_2:%.*]], label [[FAIL_LOOPEXIT1:%.*]]
+; CHECK-NEXT:    [[IV_2:%.*]] = phi i32 [ [[IV_NEXT_2:%.*]], [[GUARDED_2:%.*]] ], [ 0, [[LOOP_2_PREHEADER]] ]
+; CHECK-NEXT:    [[CHECK_2:%.*]] = icmp slt i32 [[IV_2]], [[X]]
+; CHECK-NEXT:    br i1 [[CHECK_2]], label [[GUARDED_2]], label [[FAIL_LOOPEXIT1:%.*]]
 ; CHECK:       guarded.2:
+; CHECK-NEXT:    [[IV_NEXT_2]] = add nuw i32 [[IV_2]], 1
 ; CHECK-NEXT:    [[LOOP_COND_2:%.*]] = call i1 @cond()
 ; CHECK-NEXT:    br i1 [[LOOP_COND_2]], label [[LOOP_2]], label [[EXIT_LOOPEXIT2:%.*]]
 ; CHECK:       exit.loopexit:
@@ -77,13 +80,16 @@
 ; CHECK:       loop.1.preheader:
 ; CHECK-NEXT:    br label [[LOOP_1:%.*]]
 ; CHECK:       loop.1:
-; CHECK-NEXT:    br i1 true, label [[GUARDED_1:%.*]], label [[FAIL_LOOPEXIT:%.*]]
+; CHECK-NEXT:    [[IV_1:%.*]] = phi i32 [ [[IV_NEXT_1:%.*]], [[GUARDED_1:%.*]] ], [ 0, [[LOOP_1_PREHEADER]] ]
+; CHECK-NEXT:    [[CHECK_1:%.*]] = icmp slt i32 [[IV_1]], [[X:%.*]]
+; CHECK-NEXT:    br i1 [[CHECK_1]], label [[GUARDED_1]], label [[FAIL_LOOPEXIT:%.*]]
 ; CHECK:       guarded.1:
+; CHECK-NEXT:    [[IV_NEXT_1]] = add nuw i32 [[IV_1]], 1
 ; CHECK-NEXT:    [[LOOP_COND_1:%.*]] = call i1 @cond()
 ; CHECK-NEXT:    br i1 [[LOOP_COND_1]], label [[LOOP_1]], label [[EXIT_LOOPEXIT:%.*]]
 ; CHECK:       loop.2:
 ; CHECK-NEXT:    [[IV_2:%.*]] = phi i32 [ [[IV_NEXT_2:%.*]], [[GUARDED_2:%.*]] ], [ 0, [[LOOP_2_PREHEADER]] ]
-; CHECK-NEXT:    [[CHECK_2:%.*]] = icmp slt i32 [[IV_2]], [[X:%.*]]
+; CHECK-NEXT:    [[CHECK_2:%.*]] = icmp slt i32 [[IV_2]], [[X]]
 ; CHECK-NEXT:    br i1 [[CHECK_2]], label [[GUARDED_2]], label [[FAIL_LOOPEXIT1:%.*]]
 ; CHECK:       guarded.2:
 ; CHECK-NEXT:    [[IV_NEXT_2]] = add nuw i32 [[IV_2]], 1
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -10550,6 +10550,10 @@
     return false;
   };
 
+  // The defining scope is the first point at which our operands are both
+  // defined.
+  auto *DefI = getDefiningScopeBound({LHS, RHS});
+
   // Starting at the block's predecessor, climb up the predecessor chain, as long
   // as there are predecessors that can be found that have unique successors
   // leading to the original block.
@@ -10564,6 +10568,11 @@
     if (ProveViaGuard(Pair.first))
       return true;
 
+    // There's no need to scan above the defining scope for Expr, by definition
+    // there's nothing to find in terms of further relevant conditions.
+    if (!DT.dominates(DefI, Pair.first->getTerminator()))
+      break;
+
     const BranchInst *LoopEntryPredicate =
         dyn_cast<BranchInst>(Pair.first->getTerminator());
     if (!LoopEntryPredicate ||
@@ -10582,6 +10591,10 @@
     auto *CI = cast<CallInst>(AssumeVH);
     if (!DT.dominates(CI, BB))
       continue;
+    // There's no need to scan above the defining scope for Expr, by definition
+    // there's nothing to find in terms of further relevant conditions.
+    if (!DT.dominates(DefI, CI))
+      continue;
 
     if (ProveViaCond(CI->getArgOperand(0), false))
       return true;
@@ -13699,6 +13712,7 @@
     if (RewrittenRHS)
       RewriteMap[LHSUnknown->getValue()] = RewrittenRHS;
   };
+
   // Starting at the loop predecessor, climb up the predecessor chain, as long
   // as there are predecessors that can be found that have unique successors
   // leading to the original header.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111903.380072.patch
Type: text/x-patch
Size: 3915 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211015/f665521d/attachment.bin>


More information about the llvm-commits mailing list