[Mlir-commits] [mlir] eff51cf - [MLIR][Presburger] Use Matrix utilities for IntegerPolyhedron
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Feb 25 04:08:13 PST 2022
Author: Groverkss
Date: 2022-02-25T17:35:13+05:30
New Revision: eff51cf9f32a2837ded15b81cbc872b2c8386afc
URL: https://github.com/llvm/llvm-project/commit/eff51cf9f32a2837ded15b81cbc872b2c8386afc
DIFF: https://github.com/llvm/llvm-project/commit/eff51cf9f32a2837ded15b81cbc872b2c8386afc.diff
LOG: [MLIR][Presburger] Use Matrix utilities for IntegerPolyhedron
This patch replaces various functions over inequalities/equalities in
IntegerPolyhedron with Matrix functions already implementing them or refactors
them to a Matrix function.
Reviewed By: arjunp
Differential Revision: https://reviews.llvm.org/D120482
Added:
Modified:
mlir/include/mlir/Analysis/Presburger/Matrix.h
mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp
mlir/lib/Analysis/Presburger/Matrix.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Analysis/Presburger/Matrix.h b/mlir/include/mlir/Analysis/Presburger/Matrix.h
index f94edfff37df3..ff4835ed52a5f 100644
--- a/mlir/include/mlir/Analysis/Presburger/Matrix.h
+++ b/mlir/include/mlir/Analysis/Presburger/Matrix.h
@@ -118,6 +118,16 @@ class Matrix {
/// Negate the specified column.
void negateColumn(unsigned column);
+ /// Negate the specified row.
+ void negateRow(unsigned row);
+
+ /// Divide the first `nCols` of the specified row by their GCD.
+ /// Returns the GCD of the first `nCols` of the specified row.
+ uint64_t normalizeRow(unsigned row, unsigned nCols);
+ /// Divide the columns of the specified row by their GCD.
+ /// Returns the GCD of the columns of the specified row.
+ uint64_t normalizeRow(unsigned row);
+
/// The given vector is interpreted as a row vector v. Post-multiply v with
/// this matrix, say M, and return vM.
SmallVector<int64_t, 8> preMultiplyWithRow(ArrayRef<int64_t> rowVec) const;
diff --git a/mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp b/mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp
index 10df34a37d6ac..dd3c5a8c145aa 100644
--- a/mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp
@@ -215,10 +215,8 @@ void IntegerPolyhedron::swapId(unsigned posA, unsigned posB) {
if (posA == posB)
return;
- for (unsigned r = 0, e = getNumInequalities(); r < e; r++)
- std::swap(atIneq(r, posA), atIneq(r, posB));
- for (unsigned r = 0, e = getNumEqualities(); r < e; r++)
- std::swap(atEq(r, posA), atEq(r, posB));
+ inequalities.swapColumns(posA, posB);
+ equalities.swapColumns(posA, posB);
}
void IntegerPolyhedron::clearConstraints() {
@@ -303,12 +301,11 @@ void IntegerPolyhedron::setAndEliminate(unsigned pos,
// Setting x_j = p in sum_i a_i x_i + c is equivalent to adding p*a_j to the
// constant term and removing the id x_j. We do this for all the ids
// pos, pos + 1, ... pos + values.size() - 1.
- for (unsigned r = 0, e = getNumInequalities(); r < e; r++)
- for (unsigned i = 0, numVals = values.size(); i < numVals; ++i)
- atIneq(r, getNumCols() - 1) += atIneq(r, pos + i) * values[i];
- for (unsigned r = 0, e = getNumEqualities(); r < e; r++)
- for (unsigned i = 0, numVals = values.size(); i < numVals; ++i)
- atEq(r, getNumCols() - 1) += atEq(r, pos + i) * values[i];
+ unsigned constantColPos = getNumCols() - 1;
+ for (unsigned i = 0, numVals = values.size(); i < numVals; ++i)
+ inequalities.addToColumn(i + pos, constantColPos, values[i]);
+ for (unsigned i = 0, numVals = values.size(); i < numVals; ++i)
+ equalities.addToColumn(i + pos, constantColPos, values[i]);
removeIdRange(pos, pos + values.size());
}
@@ -334,35 +331,11 @@ bool IntegerPolyhedron::findConstraintWithNonZeroAt(unsigned colIdx, bool isEq,
return false;
}
-// Normalizes the coefficient values across all columns in `rowIdx` by their
-// GCD in equality or inequality constraints as specified by `isEq`.
-template <bool isEq>
-static void normalizeConstraintByGCD(IntegerPolyhedron *constraints,
- unsigned rowIdx) {
- auto at = [&](unsigned colIdx) -> int64_t {
- return isEq ? constraints->atEq(rowIdx, colIdx)
- : constraints->atIneq(rowIdx, colIdx);
- };
- uint64_t gcd = std::abs(at(0));
- for (unsigned j = 1, e = constraints->getNumCols(); j < e; ++j) {
- gcd = llvm::GreatestCommonDivisor64(gcd, std::abs(at(j)));
- }
- if (gcd > 0 && gcd != 1) {
- for (unsigned j = 0, e = constraints->getNumCols(); j < e; ++j) {
- int64_t v = at(j) / static_cast<int64_t>(gcd);
- isEq ? constraints->atEq(rowIdx, j) = v
- : constraints->atIneq(rowIdx, j) = v;
- }
- }
-}
-
void IntegerPolyhedron::normalizeConstraintsByGCD() {
- for (unsigned i = 0, e = getNumEqualities(); i < e; ++i) {
- normalizeConstraintByGCD</*isEq=*/true>(this, i);
- }
- for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
- normalizeConstraintByGCD</*isEq=*/false>(this, i);
- }
+ for (unsigned i = 0, e = getNumEqualities(); i < e; ++i)
+ equalities.normalizeRow(i);
+ for (unsigned i = 0, e = getNumInequalities(); i < e; ++i)
+ inequalities.normalizeRow(i);
}
bool IntegerPolyhedron::hasInvalidConstraint() const {
@@ -861,17 +834,10 @@ void IntegerPolyhedron::getLocalReprs(
void IntegerPolyhedron::gcdTightenInequalities() {
unsigned numCols = getNumCols();
for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
- uint64_t gcd = std::abs(atIneq(i, 0));
- for (unsigned j = 1; j < numCols - 1; ++j) {
- gcd = llvm::GreatestCommonDivisor64(gcd, std::abs(atIneq(i, j)));
- }
- if (gcd > 0 && gcd != 1) {
- int64_t gcdI = static_cast<int64_t>(gcd);
- // Tighten the constant term and normalize the constraint by the GCD.
- atIneq(i, numCols - 1) = mlir::floorDiv(atIneq(i, numCols - 1), gcdI);
- for (unsigned j = 0, e = numCols - 1; j < e; ++j)
- atIneq(i, j) /= gcdI;
- }
+ // Normalize the constraint and tighten the constant term by the GCD.
+ uint64_t gcd = inequalities.normalizeRow(i, getNumCols() - 1);
+ if (gcd > 1)
+ atIneq(i, numCols - 1) = mlir::floorDiv(atIneq(i, numCols - 1), gcd);
}
}
@@ -906,14 +872,14 @@ unsigned IntegerPolyhedron::gaussianEliminateIds(unsigned posStart,
for (unsigned i = 0, e = getNumEqualities(); i < e; ++i) {
eliminateFromConstraint(this, i, pivotRow, pivotCol, posStart,
/*isEq=*/true);
- normalizeConstraintByGCD</*isEq=*/true>(this, i);
+ equalities.normalizeRow(i);
}
// Eliminate identifier at 'pivotCol' from each inequality row.
for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
eliminateFromConstraint(this, i, pivotRow, pivotCol, posStart,
/*isEq=*/false);
- normalizeConstraintByGCD</*isEq=*/false>(this, i);
+ inequalities.normalizeRow(i);
}
removeEquality(pivotRow);
gcdTightenInequalities();
@@ -925,21 +891,6 @@ unsigned IntegerPolyhedron::gaussianEliminateIds(unsigned posStart,
return posLimit - posStart;
}
-// Fills an inequality row with the value 'val'.
-static inline void fillInequality(IntegerPolyhedron *cst, unsigned r,
- int64_t val) {
- for (unsigned c = 0, f = cst->getNumCols(); c < f; c++) {
- cst->atIneq(r, c) = val;
- }
-}
-
-// Negates an inequality.
-static inline void negateInequality(IntegerPolyhedron *cst, unsigned r) {
- for (unsigned c = 0, f = cst->getNumCols(); c < f; c++) {
- cst->atIneq(r, c) = -cst->atIneq(r, c);
- }
-}
-
// A more complex check to eliminate redundant inequalities. Uses FourierMotzkin
// to check if a constraint is redundant.
void IntegerPolyhedron::removeRedundantInequalities() {
@@ -950,32 +901,24 @@ void IntegerPolyhedron::removeRedundantInequalities() {
IntegerPolyhedron tmpCst(*this);
for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
// Change the inequality to its complement.
- negateInequality(&tmpCst, r);
+ tmpCst.inequalities.negateRow(r);
tmpCst.atIneq(r, tmpCst.getNumCols() - 1)--;
if (tmpCst.isEmpty()) {
redun[r] = true;
// Zero fill the redundant inequality.
- fillInequality(this, r, /*val=*/0);
- fillInequality(&tmpCst, r, /*val=*/0);
+ inequalities.fillRow(r, /*value=*/0);
+ tmpCst.inequalities.fillRow(r, /*value=*/0);
} else {
// Reverse the change (to avoid recreating tmpCst each time).
tmpCst.atIneq(r, tmpCst.getNumCols() - 1)++;
- negateInequality(&tmpCst, r);
+ tmpCst.inequalities.negateRow(r);
}
}
- // Scan to get rid of all rows marked redundant, in-place.
- auto copyRow = [&](unsigned src, unsigned dest) {
- if (src == dest)
- return;
- for (unsigned c = 0, e = getNumCols(); c < e; c++) {
- atIneq(dest, c) = atIneq(src, c);
- }
- };
unsigned pos = 0;
- for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
+ for (unsigned r = 0, e = getNumInequalities(); r < e; ++r) {
if (!redun[r])
- copyRow(r, pos++);
+ inequalities.copyRow(r, pos++);
}
inequalities.resizeVertically(pos);
}
@@ -990,19 +933,13 @@ void IntegerPolyhedron::removeRedundantConstraints() {
Simplex simplex(*this);
simplex.detectRedundant();
- auto copyInequality = [&](unsigned src, unsigned dest) {
- if (src == dest)
- return;
- for (unsigned c = 0, e = getNumCols(); c < e; c++)
- atIneq(dest, c) = atIneq(src, c);
- };
unsigned pos = 0;
unsigned numIneqs = getNumInequalities();
// Scan to get rid of all inequalities marked redundant, in-place. In Simplex,
// the first constraints added are the inequalities.
for (unsigned r = 0; r < numIneqs; r++) {
if (!simplex.isMarkedRedundant(r))
- copyInequality(r, pos++);
+ inequalities.copyRow(r, pos++);
}
inequalities.resizeVertically(pos);
@@ -1010,17 +947,11 @@ void IntegerPolyhedron::removeRedundantConstraints() {
// after the inequalities, a pair of constraints for each equality is added.
// An equality is redundant if both the inequalities in its pair are
// redundant.
- auto copyEquality = [&](unsigned src, unsigned dest) {
- if (src == dest)
- return;
- for (unsigned c = 0, e = getNumCols(); c < e; c++)
- atEq(dest, c) = atEq(src, c);
- };
pos = 0;
for (unsigned r = 0, e = getNumEqualities(); r < e; r++) {
if (!(simplex.isMarkedRedundant(numIneqs + 2 * r) &&
simplex.isMarkedRedundant(numIneqs + 2 * r + 1)))
- copyEquality(r, pos++);
+ equalities.copyRow(r, pos++);
}
equalities.resizeVertically(pos);
}
@@ -1159,7 +1090,7 @@ void IntegerPolyhedron::removeRedundantLocalVars() {
// Normalize the equality constraints to reduce coefficients of local
// variables to 1 wherever possible.
for (unsigned i = 0, e = getNumEqualities(); i < e; ++i)
- normalizeConstraintByGCD</*isEq=*/true>(this, i);
+ equalities.normalizeRow(i);
while (true) {
unsigned i, e, j, f;
@@ -1183,7 +1114,7 @@ void IntegerPolyhedron::removeRedundantLocalVars() {
for (unsigned k = 0, t = getNumEqualities(); k < t; ++k) {
if (atEq(k, j) != 0) {
eliminateFromConstraint(this, k, i, j, j, /*isEq=*/true);
- normalizeConstraintByGCD</*isEq=*/true>(this, k);
+ equalities.normalizeRow(k);
}
}
diff --git a/mlir/lib/Analysis/Presburger/Matrix.cpp b/mlir/lib/Analysis/Presburger/Matrix.cpp
index 00f96e596b4cf..f44405ae12351 100644
--- a/mlir/lib/Analysis/Presburger/Matrix.cpp
+++ b/mlir/lib/Analysis/Presburger/Matrix.cpp
@@ -204,6 +204,30 @@ void Matrix::negateColumn(unsigned column) {
at(row, column) = -at(row, column);
}
+void Matrix::negateRow(unsigned row) {
+ for (unsigned column = 0, e = getNumColumns(); column < e; ++column)
+ at(row, column) = -at(row, column);
+}
+
+uint64_t Matrix::normalizeRow(unsigned row, unsigned cols) {
+ if (cols == 0)
+ return 0;
+
+ int64_t gcd = std::abs(at(row, 0));
+ for (unsigned j = 1, e = cols; j < e; ++j)
+ gcd = llvm::GreatestCommonDivisor64(gcd, std::abs(at(row, j)));
+
+ if (gcd > 1)
+ for (unsigned j = 0, e = cols; j < e; ++j)
+ at(row, j) /= gcd;
+
+ return gcd;
+}
+
+uint64_t Matrix::normalizeRow(unsigned row) {
+ return normalizeRow(row, getNumColumns());
+}
+
SmallVector<int64_t, 8>
Matrix::preMultiplyWithRow(ArrayRef<int64_t> rowVec) const {
assert(rowVec.size() == getNumRows() && "Invalid row vector dimension!");
More information about the Mlir-commits
mailing list