[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