Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion llvm/lib/Analysis/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <string>

Expand Down Expand Up @@ -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(
Expand All @@ -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<uint16_t>::max();
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down