Skip to content

Commit

Permalink
[ConstraintElim] Update existing constraint system in place (NFC).
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
fhahn committed Feb 6, 2023
1 parent 0b8eff1 commit 8537a7c
Showing 1 changed file with 23 additions and 17 deletions.
40 changes: 23 additions & 17 deletions llvm/lib/Analysis/ConstraintSystem.cpp
Expand Up @@ -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;

Expand All @@ -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))
Expand All @@ -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;
Expand Down

0 comments on commit 8537a7c

Please sign in to comment.