Skip to content

Commit bc6780b

Browse files
committed
[SCEV] Splip collecting and applying rewrite info from loop guards (NFC)
Split off collecting rewrite info from loop guards to collectRewriteInfoFromLoopGuards. This allows users of applyLoopGuards to collect rewrite info once in cases where the same loop guards are applied multiple times. This is used to collect rewrite info once in howFarToZero, which saves a bit of compile-time: stage1-O3: -0.04% stage1-ReleaseThinLTO: -0.02% stage1-ReleaseLTO-g: -0.04% stage2-O3: -0.02% https://llvm-compile-time-tracker.com/compare.php?from=117b53ae38428ca66eaa886fb432e6f09db88fe4&to=4ffb7b2e1c99081ccebe6f236c48a0be2f64b6ff&stat=instructions:u Notably this improves mafft by -0.9% with -O3, -0.11% with LTO and -0.12% with stage2-O3.
1 parent 1f9bb85 commit bc6780b

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,8 +1299,17 @@ class ScalarEvolution {
12991299
/// sharpen it.
13001300
void setNoWrapFlags(SCEVAddRecExpr *AddRec, SCEV::NoWrapFlags Flags);
13011301

1302+
/// Collect rewrite map for loop guards for loop \p L, together with flags
1303+
/// indidcating if NUW and NSW can be preserved during rewriting.
1304+
std::tuple<DenseMap<const SCEV *, const SCEV *>, bool, bool>
1305+
collectRewriteInfoFromLoopGuards(const Loop *L);
1306+
13021307
/// Try to apply information from loop guards for \p L to \p Expr.
13031308
const SCEV *applyLoopGuards(const SCEV *Expr, const Loop *L);
1309+
const SCEV *
1310+
applyLoopGuards(const SCEV *Expr, const Loop *L,
1311+
const DenseMap<const SCEV *, const SCEV *> &RewriteMap,
1312+
bool PreserveNUW, bool PreserveNSW);
13041313

13051314
/// Return true if the loop has no abnormal exits. That is, if the loop
13061315
/// is not infinite, it must exit through an explicit edge in the CFG.

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10490,8 +10490,11 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1049010490
if (!isLoopInvariant(Step, L))
1049110491
return getCouldNotCompute();
1049210492

10493+
const auto &[RewriteMap, PreserveNUW, PreserveNSW] =
10494+
collectRewriteInfoFromLoopGuards(L);
1049310495
// Specialize step for this loop so we get context sensitive facts below.
10494-
const SCEV *StepWLG = applyLoopGuards(Step, L);
10496+
const SCEV *StepWLG =
10497+
applyLoopGuards(Step, L, RewriteMap, PreserveNUW, PreserveNSW);
1049510498

1049610499
// For positive steps (counting up until unsigned overflow):
1049710500
// N = -Start/Step (as unsigned)
@@ -10508,7 +10511,8 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1050810511
// N = Distance (as unsigned)
1050910512
if (StepC &&
1051010513
(StepC->getValue()->isOne() || StepC->getValue()->isMinusOne())) {
10511-
APInt MaxBECount = getUnsignedRangeMax(applyLoopGuards(Distance, L));
10514+
APInt MaxBECount = getUnsignedRangeMax(
10515+
applyLoopGuards(Distance, L, RewriteMap, PreserveNUW, PreserveNSW));
1051210516
MaxBECount = APIntOps::umin(MaxBECount, getUnsignedRangeMax(Distance));
1051310517

1051410518
// When a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated,
@@ -10549,7 +10553,8 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1054910553
getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
1055010554
const SCEV *ConstantMax = getCouldNotCompute();
1055110555
if (Exact != getCouldNotCompute()) {
10552-
APInt MaxInt = getUnsignedRangeMax(applyLoopGuards(Exact, L));
10556+
APInt MaxInt = getUnsignedRangeMax(
10557+
applyLoopGuards(Exact, L, RewriteMap, PreserveNUW, PreserveNSW));
1055310558
ConstantMax =
1055410559
getConstant(APIntOps::umin(MaxInt, getUnsignedRangeMax(Exact)));
1055510560
}
@@ -10566,7 +10571,8 @@ ScalarEvolution::ExitLimit ScalarEvolution::howFarToZero(const SCEV *V,
1056610571

1056710572
const SCEV *M = E;
1056810573
if (E != getCouldNotCompute()) {
10569-
APInt MaxWithGuards = getUnsignedRangeMax(applyLoopGuards(E, L));
10574+
APInt MaxWithGuards = getUnsignedRangeMax(
10575+
applyLoopGuards(E, L, RewriteMap, PreserveNUW, PreserveNSW));
1057010576
M = getConstant(APIntOps::umin(MaxWithGuards, getUnsignedRangeMax(E)));
1057110577
}
1057210578
auto *S = isa<SCEVCouldNotCompute>(E) ? M : E;
@@ -15096,7 +15102,7 @@ class SCEVLoopGuardRewriter : public SCEVRewriteVisitor<SCEVLoopGuardRewriter> {
1509615102

1509715103
public:
1509815104
SCEVLoopGuardRewriter(ScalarEvolution &SE,
15099-
DenseMap<const SCEV *, const SCEV *> &M,
15105+
const DenseMap<const SCEV *, const SCEV *> &M,
1510015106
bool PreserveNUW, bool PreserveNSW)
1510115107
: SCEVRewriteVisitor(SE), Map(M) {
1510215108
if (PreserveNUW)
@@ -15191,7 +15197,8 @@ class SCEVLoopGuardRewriter : public SCEVRewriteVisitor<SCEVLoopGuardRewriter> {
1519115197
}
1519215198
};
1519315199

15194-
const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
15200+
std::tuple<DenseMap<const SCEV *, const SCEV *>, bool, bool>
15201+
ScalarEvolution::collectRewriteInfoFromLoopGuards(const Loop *L) {
1519515202
SmallVector<const SCEV *> ExprsToRewrite;
1519615203
auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
1519715204
const SCEV *RHS,
@@ -15600,9 +15607,6 @@ const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
1560015607
}
1560115608
}
1560215609

15603-
if (RewriteMap.empty())
15604-
return Expr;
15605-
1560615610
// Let the rewriter preserve NUW/NSW flags if the unsigned/signed ranges of
1560715611
// the replacement expressions are contained in the ranges of the replaced
1560815612
// expressions.
@@ -15626,6 +15630,22 @@ const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
1562615630
RewriteMap.insert({Expr, Rewriter.visit(RewriteTo)});
1562715631
}
1562815632
}
15633+
return {RewriteMap, PreserveNUW, PreserveNSW};
15634+
}
15635+
15636+
const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
15637+
const auto &[RewriteMap, PreserveNUW, PreserveNSW] =
15638+
collectRewriteInfoFromLoopGuards(L);
15639+
return applyLoopGuards(Expr, L, RewriteMap, PreserveNUW, PreserveNSW);
15640+
}
15641+
15642+
const SCEV *ScalarEvolution::applyLoopGuards(
15643+
const SCEV *Expr, const Loop *L,
15644+
const DenseMap<const SCEV *, const SCEV *> &RewriteMap, bool PreserveNUW,
15645+
bool PreserveNSW) {
15646+
if (RewriteMap.empty())
15647+
return Expr;
15648+
1562915649
SCEVLoopGuardRewriter Rewriter(*this, RewriteMap, PreserveNUW, PreserveNSW);
1563015650
return Rewriter.visit(Expr);
1563115651
}

0 commit comments

Comments
 (0)