[llvm] 8537a7c - [ConstraintElim] Update existing constraint system in place (NFC).

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 6 08:44:00 PST 2023


Author: Florian Hahn
Date: 2023-02-06T16:43:42Z
New Revision: 8537a7c91c55152534baae0735c8a7e466d489ac

URL: https://github.com/llvm/llvm-project/commit/8537a7c91c55152534baae0735c8a7e466d489ac
DIFF: https://github.com/llvm/llvm-project/commit/8537a7c91c55152534baae0735c8a7e466d489ac.diff

LOG: [ConstraintElim] Update existing constraint system in place (NFC).

This patch breaks up the solving step into 2 phases:

1. Collect all rows where the variable to eliminate is != 0 and remove
   it from the original system.
2. Process all collect rows to build new set of constraints, add them to
   the original system.

This is much more efficient for excessive cases, as this avoids a large
number of moves to the new system. This reduces the time spent in
ConstraintElimination for the test case shared in D135915 from ~3s to
0.6s.

Added: 
    

Modified: 
    llvm/lib/Analysis/ConstraintSystem.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstraintSystem.cpp b/llvm/lib/Analysis/ConstraintSystem.cpp
index 633427ee6c5b..fd96c61e9a94 100644
--- a/llvm/lib/Analysis/ConstraintSystem.cpp
+++ b/llvm/lib/Analysis/ConstraintSystem.cpp
@@ -28,32 +28,39 @@ bool ConstraintSystem::eliminateUsingFM() {
   assert(!Constraints.empty() &&
          "should only be called for non-empty constraint systems");
   unsigned NumVariables = Constraints[0].size();
-  SmallVector<SmallVector<int64_t, 8>, 4> NewSystem;
 
-  unsigned NumConstraints = Constraints.size();
   uint32_t NewGCD = 1;
   unsigned LastIdx = NumVariables - 1;
 
-  for (unsigned R1 = 0; R1 < NumConstraints; R1++) {
+  // First, either remove the variable in place if it is 0 or add the row to
+  // RemainingRows and remove it from the system.
+  SmallVector<SmallVector<int64_t, 8>, 4> RemainingRows;
+  for (unsigned R1 = 0; R1 < Constraints.size();) {
     SmallVector<int64_t, 8> &Row1 = Constraints[R1];
     int64_t LowerLast = Row1[LastIdx];
     if (LowerLast == 0) {
       Row1.pop_back();
-      NewSystem.push_back(std::move(Row1));
-      continue;
+      R1++;
+    } else {
+      std::swap(Constraints[R1], Constraints.back());
+      RemainingRows.push_back(std::move(Constraints.back()));
+      Constraints.pop_back();
     }
+  }
 
+  // Process rows where the variable is != 0.
+  unsigned NumRemainingConstraints = RemainingRows.size();
+  for (unsigned R1 = 0; R1 < NumRemainingConstraints; R1++) {
     // FIXME do not use copy
-    for (unsigned R2 = R1 + 1; R2 < NumConstraints; R2++) {
+    for (unsigned R2 = R1 + 1; R2 < NumRemainingConstraints; R2++) {
       if (R1 == R2)
         continue;
 
-      int64_t UpperLast = Constraints[R2][LastIdx];
-      // FIXME: can we do better than just dropping things here?
-      if (UpperLast == 0)
-        continue;
-
-      int64_t LowerLast = Constraints[R1][LastIdx];
+      int64_t UpperLast = RemainingRows[R2][LastIdx];
+      int64_t LowerLast = RemainingRows[R1][LastIdx];
+      assert(
+          UpperLast != 0 && LowerLast != 0 &&
+          "RemainingRows should only contain rows where the variable is != 0");
       if ((LowerLast < 0 && UpperLast < 0) || (LowerLast > 0 && UpperLast > 0))
         continue;
 
@@ -67,10 +74,10 @@ bool ConstraintSystem::eliminateUsingFM() {
       SmallVector<int64_t, 8> NR;
       for (unsigned I = 0; I < LastIdx; I++) {
         int64_t M1, M2, N;
-        int64_t UpperV = Constraints[UpperR][I];
+        int64_t UpperV = RemainingRows[UpperR][I];
         if (MulOverflow(UpperV, ((-1) * LowerLast / GCD), M1))
           return false;
-        int64_t LowerV = Constraints[LowerR][I];
+        int64_t LowerV = RemainingRows[LowerR][I];
         if (MulOverflow(LowerV, (UpperLast / GCD), M2))
           return false;
         if (AddOverflow(M1, M2, N))
@@ -81,13 +88,12 @@ bool ConstraintSystem::eliminateUsingFM() {
             APIntOps::GreatestCommonDivisor({32, (uint32_t)N}, {32, NewGCD})
                 .getZExtValue();
       }
-      NewSystem.push_back(std::move(NR));
+      Constraints.push_back(std::move(NR));
       // Give up if the new system gets too big.
-      if (NewSystem.size() > 500)
+      if (Constraints.size() > 500)
         return false;
     }
   }
-  Constraints = std::move(NewSystem);
   GCD = NewGCD;
 
   return true;


        


More information about the llvm-commits mailing list