diff --git a/llvm/lib/Analysis/ConstraintSystem.cpp b/llvm/lib/Analysis/ConstraintSystem.cpp index 7216a0219080f..6457b6b425c6c 100644 --- a/llvm/lib/Analysis/ConstraintSystem.cpp +++ b/llvm/lib/Analysis/ConstraintSystem.cpp @@ -8,10 +8,10 @@ #include "llvm/Analysis/ConstraintSystem.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/MathExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Value.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #include @@ -52,6 +52,12 @@ bool ConstraintSystem::eliminateUsingFM() { for (unsigned R1 = 0; R1 < NumRemainingConstraints; R1++) { // FIXME do not use copy for (unsigned R2 = R1 + 1; R2 < NumRemainingConstraints; R2++) { + // Examples of constraints stored as {Constant, Coeff_x, Coeff_y} + // R1: 0 >= 1 * x + (-2) * y => { 0, 1, -2 } + // R2: 3 >= 2 * x + 3 * y => { 3, 2, 3 } + // LastIdx = 2 (tracking coefficient of y) + // UpperLast: 3 + // LowerLast: -2 int64_t UpperLast = getLastCoefficient(RemainingRows[R2], LastIdx); int64_t LowerLast = getLastCoefficient(RemainingRows[R1], LastIdx); assert( @@ -73,10 +79,13 @@ bool ConstraintSystem::eliminateUsingFM() { unsigned IdxLower = 0; auto &LowerRow = RemainingRows[LowerR]; auto &UpperRow = RemainingRows[UpperR]; + // Update constant and coefficients of both constraints. + // Stops until every coefficient is updated or overflows. while (true) { if (IdxUpper >= UpperRow.size() || IdxLower >= LowerRow.size()) break; int64_t M1, M2, N; + // Starts with index 0 and updates every coefficients. int64_t UpperV = 0; int64_t LowerV = 0; uint16_t CurrentId = std::numeric_limits::max(); @@ -101,8 +110,23 @@ bool ConstraintSystem::eliminateUsingFM() { if (MulOverflow(LowerV, UpperLast, M2)) return false; + // This algorithm is a variant of sparse Gaussian elimination. + // + // The new coefficient for CurrentId is + // N = UpperV * (-1) * LowerLast + LowerV * UpperLast + // + // UpperRow: { 3, 2, 3 }, LowerLast: -2 + // LowerRow: { 0, 1, -2 }, UpperLast: 3 + // + // After multiplication: + // UpperRow: { 6, 4, 6 } + // LowerRow: { 0, 3, -6 } + // + // Eliminates y after addition: + // N: { 6, 7, 0 } => 6 >= 7 * x if (AddOverflow(M1, M2, N)) return false; + // Skip variable that is completely eliminated. if (N == 0) continue; NR.emplace_back(N, CurrentId); diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index e0861fbedc560..8f379db1ca2fc 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -239,7 +239,7 @@ struct ConstraintTy { unsigned empty() const { return Coefficients.empty(); } /// Returns true if all preconditions for this list of constraints are - /// satisfied given \p CS and the corresponding \p Value2Index mapping. + /// satisfied given \p Info. bool isValid(const ConstraintInfo &Info) const; bool isEq() const { return IsEq; }