8
8
9
9
#include " llvm/Analysis/ConstraintSystem.h"
10
10
#include " llvm/ADT/SmallVector.h"
11
- #include " llvm/Support/MathExtras.h"
12
11
#include " llvm/ADT/StringExtras.h"
13
12
#include " llvm/IR/Value.h"
14
13
#include " llvm/Support/Debug.h"
14
+ #include " llvm/Support/MathExtras.h"
15
15
16
16
#include < string>
17
17
@@ -52,6 +52,12 @@ bool ConstraintSystem::eliminateUsingFM() {
52
52
for (unsigned R1 = 0 ; R1 < NumRemainingConstraints; R1++) {
53
53
// FIXME do not use copy
54
54
for (unsigned R2 = R1 + 1 ; R2 < NumRemainingConstraints; R2++) {
55
+ // Examples of constraints stored as {Constant, Coeff_x, Coeff_y}
56
+ // R1: 0 >= 1 * x + (-2) * y => { 0, 1, -2 }
57
+ // R2: 3 >= 2 * x + 3 * y => { 3, 2, 3 }
58
+ // LastIdx = 2 (tracking coefficient of y)
59
+ // UpperLast: 3
60
+ // LowerLast: -2
55
61
int64_t UpperLast = getLastCoefficient (RemainingRows[R2], LastIdx);
56
62
int64_t LowerLast = getLastCoefficient (RemainingRows[R1], LastIdx);
57
63
assert (
@@ -73,10 +79,13 @@ bool ConstraintSystem::eliminateUsingFM() {
73
79
unsigned IdxLower = 0 ;
74
80
auto &LowerRow = RemainingRows[LowerR];
75
81
auto &UpperRow = RemainingRows[UpperR];
82
+ // Update constant and coefficients of both constraints.
83
+ // Stops until every coefficient is updated or overflows.
76
84
while (true ) {
77
85
if (IdxUpper >= UpperRow.size () || IdxLower >= LowerRow.size ())
78
86
break ;
79
87
int64_t M1, M2, N;
88
+ // Starts with index 0 and updates every coefficients.
80
89
int64_t UpperV = 0 ;
81
90
int64_t LowerV = 0 ;
82
91
uint16_t CurrentId = std::numeric_limits<uint16_t >::max ();
@@ -101,8 +110,23 @@ bool ConstraintSystem::eliminateUsingFM() {
101
110
102
111
if (MulOverflow (LowerV, UpperLast, M2))
103
112
return false ;
113
+ // This algorithm is a variant of sparse Gaussian elimination.
114
+ //
115
+ // The new coefficient for CurrentId is
116
+ // N = UpperV * (-1) * LowerLast + LowerV * UpperLast
117
+ //
118
+ // UpperRow: { 3, 2, 3 }, LowerLast: -2
119
+ // LowerRow: { 0, 1, -2 }, UpperLast: 3
120
+ //
121
+ // After multiplication:
122
+ // UpperRow: { 6, 4, 6 }
123
+ // LowerRow: { 0, 3, -6 }
124
+ //
125
+ // Eliminates y after addition:
126
+ // N: { 6, 7, 0 } => 6 >= 7 * x
104
127
if (AddOverflow (M1, M2, N))
105
128
return false ;
129
+ // Skip variable that is completely eliminated.
106
130
if (N == 0 )
107
131
continue ;
108
132
NR.emplace_back (N, CurrentId);
0 commit comments