88
99#include " llvm/Analysis/ConstraintSystem.h"
1010#include " llvm/ADT/SmallVector.h"
11- #include " llvm/Support/MathExtras.h"
1211#include " llvm/ADT/StringExtras.h"
1312#include " llvm/IR/Value.h"
1413#include " llvm/Support/Debug.h"
14+ #include " llvm/Support/MathExtras.h"
1515
1616#include < string>
1717
@@ -52,6 +52,12 @@ bool ConstraintSystem::eliminateUsingFM() {
5252 for (unsigned R1 = 0 ; R1 < NumRemainingConstraints; R1++) {
5353 // FIXME do not use copy
5454 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
5561 int64_t UpperLast = getLastCoefficient (RemainingRows[R2], LastIdx);
5662 int64_t LowerLast = getLastCoefficient (RemainingRows[R1], LastIdx);
5763 assert (
@@ -73,10 +79,13 @@ bool ConstraintSystem::eliminateUsingFM() {
7379 unsigned IdxLower = 0 ;
7480 auto &LowerRow = RemainingRows[LowerR];
7581 auto &UpperRow = RemainingRows[UpperR];
82+ // Update constant and coefficients of both constraints.
83+ // Stops until every coefficient is updated or overflows.
7684 while (true ) {
7785 if (IdxUpper >= UpperRow.size () || IdxLower >= LowerRow.size ())
7886 break ;
7987 int64_t M1, M2, N;
88+ // Starts with index 0 and updates every coefficients.
8089 int64_t UpperV = 0 ;
8190 int64_t LowerV = 0 ;
8291 uint16_t CurrentId = std::numeric_limits<uint16_t >::max ();
@@ -101,8 +110,23 @@ bool ConstraintSystem::eliminateUsingFM() {
101110
102111 if (MulOverflow (LowerV, UpperLast, M2))
103112 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
104127 if (AddOverflow (M1, M2, N))
105128 return false ;
129+ // Skip variable that is completely eliminated.
106130 if (N == 0 )
107131 continue ;
108132 NR.emplace_back (N, CurrentId);
0 commit comments