[llvm] [SCEV] Avoid erase+insert in constant folding (NFC) (PR #101642)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 2 02:05:12 PDT 2024


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/101642

Based on Philip's suggestion in #101473, this changes the constant folding implementation to keep the SCEVConstant as the first element in the Ops, instead of erasing it and then later reinserting.

This gives a small compile-time improvement:
http://llvm-compile-time-tracker.com/compare.php?from=85c5265feae82d8e26869adf4505b448b3a17534&to=67271fa74cb49ff958865bc56e3eea79a934bafc&stat=instructions:u

>From 919a6b8dc0f2838f5f0f251994d1e2cf41b3466d Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 2 Aug 2024 10:09:15 +0200
Subject: [PATCH] [SCEV] Avoid erase+insert in constant folding (NFC)

Based on Philip's suggestion in #101473, this changes the constant
folding implementation to keep the SCEVConstant as the first
element in the Ops, instead of erasing it and then later reinserting.

This gives a small compile-time improvement:
http://llvm-compile-time-tracker.com/compare.php?from=85c5265feae82d8e26869adf4505b448b3a17534&to=67271fa74cb49ff958865bc56e3eea79a934bafc&stat=instructions:u
---
 llvm/lib/Analysis/ScalarEvolution.cpp | 43 +++++++++++++++------------
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 06dd17dd3648b..f4c4dbd252dd7 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -777,7 +777,7 @@ CompareSCEVComplexity(EquivalenceClasses<const SCEV *> &EqCacheSCEV,
 /// results from this routine.  In other words, we don't want the results of
 /// this to depend on where the addresses of various SCEV objects happened to
 /// land in memory.
-static void GroupByComplexity(SmallVectorImpl<const SCEV *> &Ops,
+static void GroupByComplexity(MutableArrayRef<const SCEV *> Ops,
                               LoopInfo *LI, DominatorTree &DT) {
   if (Ops.size() < 2) return;  // Noop
 
@@ -844,34 +844,39 @@ static const SCEV *
 constantFoldAndGroupOps(ScalarEvolution &SE, LoopInfo &LI, DominatorTree &DT,
                         SmallVectorImpl<const SCEV *> &Ops, FoldT Fold,
                         IsIdentityT IsIdentity, IsAbsorberT IsAbsorber) {
-  const SCEVConstant *Folded = nullptr;
+  bool HasConst = false;
   for (unsigned Idx = 0; Idx < Ops.size();) {
     const SCEV *Op = Ops[Idx];
     if (const auto *C = dyn_cast<SCEVConstant>(Op)) {
-      if (!Folded)
-        Folded = C;
-      else
-        Folded = cast<SCEVConstant>(
-            SE.getConstant(Fold(Folded->getAPInt(), C->getAPInt())));
-      Ops.erase(Ops.begin() + Idx);
-      continue;
+      if (!HasConst) {
+        // Move the constant to the start.
+        std::swap(Ops[0], Ops[Idx]);
+        HasConst = true;
+      } else {
+        Ops[0] = SE.getConstant(
+            Fold(cast<SCEVConstant>(Ops[0])->getAPInt(), C->getAPInt()));
+        Ops.erase(Ops.begin() + Idx);
+        // Revisit this index.
+        continue;
+      }
     }
     ++Idx;
   }
 
-  if (Ops.empty()) {
-    assert(Folded && "Must have folded value");
-    return Folded;
-  }
+  if (Ops.size() == 1)
+    return Ops[0];
 
-  if (Folded && IsAbsorber(Folded->getAPInt()))
-    return Folded;
+  if (HasConst && IsIdentity(cast<SCEVConstant>(Ops[0])->getAPInt())) {
+    Ops.erase(Ops.begin());
+    HasConst = false;
+  }
 
-  GroupByComplexity(Ops, &LI, DT);
-  if (Folded && !IsIdentity(Folded->getAPInt()))
-    Ops.insert(Ops.begin(), Folded);
+  if (Ops.size() == 1 ||
+      (HasConst && IsAbsorber(cast<SCEVConstant>(Ops[0])->getAPInt())))
+    return Ops[0];
 
-  return Ops.size() == 1 ? Ops[0] : nullptr;
+  GroupByComplexity(MutableArrayRef(Ops).drop_front(HasConst), &LI, DT);
+  return nullptr;
 }
 
 //===----------------------------------------------------------------------===//



More information about the llvm-commits mailing list