[MLIR] Use IntegerPolyhedron in Simplex instead of FlatAffineConstraints

This patch replaces usage of FlatAffineConstraints in Simplex with
IntegerPolyhedron. This removes dependency of Simplex on FlatAffineConstraints
and puts it on IntegerPolyhedron, which is part of Presburger library.

Reviewed By: arjunp

Differential Revision: https://reviews.llvm.org/D116287
This commit is contained in:
Groverkss 2021-12-27 19:06:32 +05:30
parent a0a0eb192e
commit 5f22f248d8
4 changed files with 32 additions and 34 deletions

View File

@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
// Functionality to perform analysis on FlatAffineConstraints. In particular,
// Functionality to perform analysis on an IntegerPolyhedron. In particular,
// support for performing emptiness checks and redundancy checks.
//
//===----------------------------------------------------------------------===//
@ -14,8 +14,8 @@
#ifndef MLIR_ANALYSIS_PRESBURGER_SIMPLEX_H
#define MLIR_ANALYSIS_PRESBURGER_SIMPLEX_H
#include "mlir/Analysis/AffineStructures.h"
#include "mlir/Analysis/Presburger/Fraction.h"
#include "mlir/Analysis/Presburger/IntegerPolyhedron.h"
#include "mlir/Analysis/Presburger/Matrix.h"
#include "mlir/IR/Location.h"
#include "mlir/Support/LogicalResult.h"
@ -39,7 +39,7 @@ class GBRSimplex;
/// sets. Furthermore, it can find a subset of these constraints that are
/// redundant, i.e. a subset of constraints that doesn't constrain the affine
/// set further after adding the non-redundant constraints. Simplex can also be
/// constructed from a FlatAffineConstraints object.
/// constructed from an IntegerPolyhedron object.
///
/// The implementation of the Simplex and SimplexBase classes, other than the
/// functionality for sampling, is based on the paper
@ -146,7 +146,7 @@ public:
SimplexBase() = delete;
explicit SimplexBase(unsigned nVar);
explicit SimplexBase(const FlatAffineConstraints &constraints);
explicit SimplexBase(const IntegerPolyhedron &constraints);
/// Returns true if the tableau is empty (has conflicting constraints),
/// false otherwise.
@ -180,8 +180,8 @@ public:
/// Rollback to a snapshot. This invalidates all later snapshots.
void rollback(unsigned snapshot);
/// Add all the constraints from the given FlatAffineConstraints.
void intersectFlatAffineConstraints(const FlatAffineConstraints &fac);
/// Add all the constraints from the given IntegerPolyhedron.
void intersectIntegerPolyhedron(const IntegerPolyhedron &fac);
/// Returns a rational sample point. This should not be called when Simplex is
/// empty.
@ -330,7 +330,7 @@ class Simplex : public SimplexBase {
public:
Simplex() = delete;
explicit Simplex(unsigned nVar) : SimplexBase(nVar) {}
explicit Simplex(const FlatAffineConstraints &constraints)
explicit Simplex(const IntegerPolyhedron &constraints)
: SimplexBase(constraints) {}
/// Compute the maximum or minimum value of the given row, depending on
@ -389,7 +389,7 @@ public:
/// Returns true if this Simplex's polytope is a rational subset of `fac`.
/// Otherwise, returns false.
bool isRationalSubsetOf(const FlatAffineConstraints &fac);
bool isRationalSubsetOf(const IntegerPolyhedron &fac);
private:
friend class GBRSimplex;

View File

@ -28,7 +28,7 @@ SimplexBase::SimplexBase(unsigned nVar)
}
}
SimplexBase::SimplexBase(const FlatAffineConstraints &constraints)
SimplexBase::SimplexBase(const IntegerPolyhedron &constraints)
: SimplexBase(constraints.getNumIds()) {
for (unsigned i = 0, numIneqs = constraints.getNumInequalities();
i < numIneqs; ++i)
@ -502,15 +502,14 @@ void SimplexBase::appendVariable(unsigned count) {
undoLog.insert(undoLog.end(), count, UndoLogEntry::RemoveLastVariable);
}
/// Add all the constraints from the given FlatAffineConstraints.
void SimplexBase::intersectFlatAffineConstraints(
const FlatAffineConstraints &fac) {
assert(fac.getNumIds() == getNumVariables() &&
"FlatAffineConstraints must have same dimensionality as simplex");
for (unsigned i = 0, e = fac.getNumInequalities(); i < e; ++i)
addInequality(fac.getInequality(i));
for (unsigned i = 0, e = fac.getNumEqualities(); i < e; ++i)
addEquality(fac.getEquality(i));
/// Add all the constraints from the given IntegerPolyhedron.
void SimplexBase::intersectIntegerPolyhedron(const IntegerPolyhedron &poly) {
assert(poly.getNumIds() == getNumVariables() &&
"IntegerPolyhedron must have same dimensionality as simplex");
for (unsigned i = 0, e = poly.getNumInequalities(); i < e; ++i)
addInequality(poly.getInequality(i));
for (unsigned i = 0, e = poly.getNumEqualities(); i < e; ++i)
addEquality(poly.getEquality(i));
}
Optional<Fraction> Simplex::computeRowOptimum(Direction direction,
@ -1285,16 +1284,16 @@ void SimplexBase::print(raw_ostream &os) const {
void SimplexBase::dump() const { print(llvm::errs()); }
bool Simplex::isRationalSubsetOf(const FlatAffineConstraints &fac) {
bool Simplex::isRationalSubsetOf(const IntegerPolyhedron &poly) {
if (isEmpty())
return true;
for (unsigned i = 0, e = fac.getNumInequalities(); i < e; ++i)
if (!isRedundantInequality(fac.getInequality(i)))
for (unsigned i = 0, e = poly.getNumInequalities(); i < e; ++i)
if (!isRedundantInequality(poly.getInequality(i)))
return false;
for (unsigned i = 0, e = fac.getNumEqualities(); i < e; ++i)
if (!isRedundantEquality(fac.getEquality(i)))
for (unsigned i = 0, e = poly.getNumEqualities(); i < e; ++i)
if (!isRedundantEquality(poly.getEquality(i)))
return false;
return true;

View File

@ -242,7 +242,7 @@ static void subtractRecursively(FlatAffineConstraints &b, Simplex &simplex,
simplex.appendVariable(numLocalsAdded);
unsigned snapshotBeforeIntersect = simplex.getSnapshot();
simplex.intersectFlatAffineConstraints(sI);
simplex.intersectIntegerPolyhedron(sI);
if (simplex.isEmpty()) {
/// b ^ s_i is empty, so b \ s_i = b. We move directly to i + 1.

View File

@ -476,24 +476,23 @@ TEST(SimplexTest, isRedundantEquality) {
EXPECT_TRUE(simplex.isRedundantEquality({-1, 0, 2})); // x = 2.
}
static FlatAffineConstraints parseFAC(StringRef str, MLIRContext *context) {
FailureOr<FlatAffineConstraints> fac = parseIntegerSetToFAC(str, context);
static IntegerPolyhedron parsePoly(StringRef str, MLIRContext *context) {
FailureOr<IntegerPolyhedron> poly = parseIntegerSetToFAC(str, context);
EXPECT_TRUE(succeeded(fac));
EXPECT_TRUE(succeeded(poly));
return *fac;
return *poly;
}
TEST(SimplexTest, IsRationalSubsetOf) {
MLIRContext context;
FlatAffineConstraints univ = FlatAffineConstraints::getUniverse(1, 0);
FlatAffineConstraints empty =
parseFAC("(x) : (x + 0 >= 0, -x - 1 >= 0)", &context);
FlatAffineConstraints s1 = parseFAC("(x) : ( x >= 0, -x + 4 >= 0)", &context);
FlatAffineConstraints s2 =
parseFAC("(x) : (x - 1 >= 0, -x + 3 >= 0)", &context);
IntegerPolyhedron univ = parsePoly("(x) : ()", &context);
IntegerPolyhedron empty =
parsePoly("(x) : (x + 0 >= 0, -x - 1 >= 0)", &context);
IntegerPolyhedron s1 = parsePoly("(x) : ( x >= 0, -x + 4 >= 0)", &context);
IntegerPolyhedron s2 = parsePoly("(x) : (x - 1 >= 0, -x + 3 >= 0)", &context);
Simplex simUniv(univ);
Simplex simEmpty(empty);