diff options
author | Florian Hahn <flo@fhahn.com> | 2024-04-12 22:07:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-12 22:07:29 +0100 |
commit | 0f82469314f34a086669dfcd190a9f89260fbee5 (patch) | |
tree | 9e705e4477681396a91b9f16a74a2c27b4e2402d /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | |
parent | 8a4b7de91dc334c828674aa2cad927c6ffb9cf37 (diff) | |
download | llvm-0f82469314f34a086669dfcd190a9f89260fbee5.zip llvm-0f82469314f34a086669dfcd190a9f89260fbee5.tar.gz llvm-0f82469314f34a086669dfcd190a9f89260fbee5.tar.bz2 |
[Passes] Run SimpleLoopUnswitch after introducing invariant branches. (#81271)
IndVars may be able to replace a loop dependent condition with a loop
invariant one, but loop-unswitch runs before IndVars, so the invariant
check remains in the loop.
For an example, consider a read-only loop with a bounds check:
https://godbolt.org/z/8cdj4qhbG
This patch uses a approach similar to the way extra cleanup passes are
run on demand after vectorization (added in acea6e9cfa4c4a0e8678c7).
It introduces a new ShouldRunExtraSimpleLoopUnswitch analysis marker,
which IndVars can use to indicate that extra unswitching is beneficial.
ExtraSimpleLoopUnswitchPassManager uses this analysis to determine
whether to run its passes on a loop.
Compile-time impact (geomean) ranges from +0.0% to 0.02%
https://llvm-compile-time-tracker.com/compare.php?from=138c0beb109ffe47f75a0fe8c4dc2cdabe8a6532&to=19e6e99eeb280d426907ea73a21b139ba7225627&stat=instructions%3Au
Compile-time impact (geomean) of unconditionally running
SimpleLoopUnswitch ranges from +0.05% - +0.16%
https://llvm-compile-time-tracker.com/compare.php?from=138c0beb109ffe47f75a0fe8c4dc2cdabe8a6532&to=2930dfd5accdce2e6f8d5146ae4d626add2065a2&stat=instructions:u
Unconditionally running SimpleLoopUnswitch seems to indicate that there
are multiple other scenarios where we fail to run unswitching when
opportunities remain.
Fixes https://github.com/llvm/llvm-project/issues/85551.
PR: https://github.com/llvm/llvm-project/pull/81271
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp index f6d7226..440fe07 100644 --- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -60,6 +60,7 @@ namespace { SmallVectorImpl<WeakTrackingVH> &DeadInsts; bool Changed = false; + bool RunUnswitching = false; public: SimplifyIndvar(Loop *Loop, ScalarEvolution *SE, DominatorTree *DT, @@ -72,6 +73,7 @@ namespace { } bool hasChanged() const { return Changed; } + bool runUnswitching() const { return RunUnswitching; } /// Iteratively perform simplification on a worklist of users of the /// specified induction variable. This is the top-level driver that applies @@ -233,6 +235,7 @@ bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp, ICmp->setPredicate(InvariantPredicate); ICmp->setOperand(0, NewLHS); ICmp->setOperand(1, NewRHS); + RunUnswitching = true; return true; } @@ -993,14 +996,18 @@ void IVVisitor::anchor() { } /// Simplify instructions that use this induction variable /// by using ScalarEvolution to analyze the IV's recurrence. -bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT, - LoopInfo *LI, const TargetTransformInfo *TTI, - SmallVectorImpl<WeakTrackingVH> &Dead, - SCEVExpander &Rewriter, IVVisitor *V) { +/// Returns a pair where the first entry indicates that the function makes +/// changes and the second entry indicates that it introduced new opportunities +/// for loop unswitching. +std::pair<bool, bool> simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, + DominatorTree *DT, LoopInfo *LI, + const TargetTransformInfo *TTI, + SmallVectorImpl<WeakTrackingVH> &Dead, + SCEVExpander &Rewriter, IVVisitor *V) { SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, DT, LI, TTI, Rewriter, Dead); SIV.simplifyUsers(CurrIV, V); - return SIV.hasChanged(); + return {SIV.hasChanged(), SIV.runUnswitching()}; } /// Simplify users of induction variables within this @@ -1014,8 +1021,9 @@ bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT, #endif bool Changed = false; for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) { - Changed |= + const auto &[C, _] = simplifyUsersOfIV(cast<PHINode>(I), SE, DT, LI, TTI, Dead, Rewriter); + Changed |= C; } return Changed; } |