aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2025-07-17 16:47:54 +0200
committerGitHub <noreply@github.com>2025-07-17 15:47:54 +0100
commit46357438baefbdcf630abc5d74565afcbf1c48dd (patch)
tree0ab6f5c053e25fe0674566aa6466b82a954cfd22 /llvm/lib
parent8f18dde6c0b38a67ad0f06aab79cdadb78b35d33 (diff)
downloadllvm-46357438baefbdcf630abc5d74565afcbf1c48dd.zip
llvm-46357438baefbdcf630abc5d74565afcbf1c48dd.tar.gz
llvm-46357438baefbdcf630abc5d74565afcbf1c48dd.tar.bz2
[SCEV] Try to re-use existing LCSSA phis when expanding SCEVAddRecExpr. (#147214)
If an AddRec is expanded outside a loop with a single exit block, check if any of the (lcssa) phi nodes in the exit block match the AddRec. If that's the case, simply use the existing lcssa phi. This can reduce the number of instruction created for SCEV expansions, mainly for runtime checks generated by the loop vectorizer. Compile-time impact should be mostly neutral https://llvm-compile-time-tracker.com/compare.php?from=48c7a3187f9831304a38df9bdb3b4d5bf6b6b1a2&to=cf9d039a7b0db5d0d912e0e2c01b19c2a653273a&stat=instructions:u PR: https://github.com/llvm/llvm-project/pull/147214
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 739ac00..ed08c0b 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -1223,6 +1223,24 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
return Result;
}
+Value *SCEVExpander::tryToReuseLCSSAPhi(const SCEVAddRecExpr *S) {
+ const Loop *L = S->getLoop();
+ BasicBlock *EB = L->getExitBlock();
+ if (!EB || !EB->getSinglePredecessor() ||
+ !SE.DT.dominates(EB, Builder.GetInsertBlock()))
+ return nullptr;
+
+ for (auto &PN : EB->phis()) {
+ if (!SE.isSCEVable(PN.getType()) || PN.getType() != S->getType())
+ continue;
+ auto *ExitV = SE.getSCEV(&PN);
+ if (S == ExitV)
+ return &PN;
+ }
+
+ return nullptr;
+}
+
Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
// In canonical mode we compute the addrec as an expression of a canonical IV
// using evaluateAtIteration and expand the resulting SCEV expression. This
@@ -1262,6 +1280,11 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
return V;
}
+ // If S is expanded outside the defining loop, check if there is a
+ // matching LCSSA phi node for it.
+ if (Value *V = tryToReuseLCSSAPhi(S))
+ return V;
+
// {X,+,F} --> X + {0,+,F}
if (!S->getStart()->isZero()) {
if (isa<PointerType>(S->getType())) {