Skip to content

Commit 8537a7c

Browse files
committed
[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.
1 parent 0b8eff1 commit 8537a7c

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

llvm/lib/Analysis/ConstraintSystem.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,39 @@ bool ConstraintSystem::eliminateUsingFM() {
2828
assert(!Constraints.empty() &&
2929
"should only be called for non-empty constraint systems");
3030
unsigned NumVariables = Constraints[0].size();
31-
SmallVector<SmallVector<int64_t, 8>, 4> NewSystem;
3231

33-
unsigned NumConstraints = Constraints.size();
3432
uint32_t NewGCD = 1;
3533
unsigned LastIdx = NumVariables - 1;
3634

37-
for (unsigned R1 = 0; R1 < NumConstraints; R1++) {
35+
// First, either remove the variable in place if it is 0 or add the row to
36+
// RemainingRows and remove it from the system.
37+
SmallVector<SmallVector<int64_t, 8>, 4> RemainingRows;
38+
for (unsigned R1 = 0; R1 < Constraints.size();) {
3839
SmallVector<int64_t, 8> &Row1 = Constraints[R1];
3940
int64_t LowerLast = Row1[LastIdx];
4041
if (LowerLast == 0) {
4142
Row1.pop_back();
42-
NewSystem.push_back(std::move(Row1));
43-
continue;
43+
R1++;
44+
} else {
45+
std::swap(Constraints[R1], Constraints.back());
46+
RemainingRows.push_back(std::move(Constraints.back()));
47+
Constraints.pop_back();
4448
}
49+
}
4550

51+
// Process rows where the variable is != 0.
52+
unsigned NumRemainingConstraints = RemainingRows.size();
53+
for (unsigned R1 = 0; R1 < NumRemainingConstraints; R1++) {
4654
// FIXME do not use copy
47-
for (unsigned R2 = R1 + 1; R2 < NumConstraints; R2++) {
55+
for (unsigned R2 = R1 + 1; R2 < NumRemainingConstraints; R2++) {
4856
if (R1 == R2)
4957
continue;
5058

51-
int64_t UpperLast = Constraints[R2][LastIdx];
52-
// FIXME: can we do better than just dropping things here?
53-
if (UpperLast == 0)
54-
continue;
55-
56-
int64_t LowerLast = Constraints[R1][LastIdx];
59+
int64_t UpperLast = RemainingRows[R2][LastIdx];
60+
int64_t LowerLast = RemainingRows[R1][LastIdx];
61+
assert(
62+
UpperLast != 0 && LowerLast != 0 &&
63+
"RemainingRows should only contain rows where the variable is != 0");
5764
if ((LowerLast < 0 && UpperLast < 0) || (LowerLast > 0 && UpperLast > 0))
5865
continue;
5966

@@ -67,10 +74,10 @@ bool ConstraintSystem::eliminateUsingFM() {
6774
SmallVector<int64_t, 8> NR;
6875
for (unsigned I = 0; I < LastIdx; I++) {
6976
int64_t M1, M2, N;
70-
int64_t UpperV = Constraints[UpperR][I];
77+
int64_t UpperV = RemainingRows[UpperR][I];
7178
if (MulOverflow(UpperV, ((-1) * LowerLast / GCD), M1))
7279
return false;
73-
int64_t LowerV = Constraints[LowerR][I];
80+
int64_t LowerV = RemainingRows[LowerR][I];
7481
if (MulOverflow(LowerV, (UpperLast / GCD), M2))
7582
return false;
7683
if (AddOverflow(M1, M2, N))
@@ -81,13 +88,12 @@ bool ConstraintSystem::eliminateUsingFM() {
8188
APIntOps::GreatestCommonDivisor({32, (uint32_t)N}, {32, NewGCD})
8289
.getZExtValue();
8390
}
84-
NewSystem.push_back(std::move(NR));
91+
Constraints.push_back(std::move(NR));
8592
// Give up if the new system gets too big.
86-
if (NewSystem.size() > 500)
93+
if (Constraints.size() > 500)
8794
return false;
8895
}
8996
}
90-
Constraints = std::move(NewSystem);
9197
GCD = NewGCD;
9298

9399
return true;

0 commit comments

Comments
 (0)