[Mlir-commits] [mlir] 6f9afad - [MLIR] Move Presburger Math from FlatAffineConstraints to Presburger/IntegerPolyhedron

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Dec 9 03:13:29 PST 2021


Author: Groverkss
Date: 2021-12-09T16:42:06+05:30
New Revision: 6f9afad6d37be5125f061c9b43ebe4312441d3a0

URL: https://github.com/llvm/llvm-project/commit/6f9afad6d37be5125f061c9b43ebe4312441d3a0
DIFF: https://github.com/llvm/llvm-project/commit/6f9afad6d37be5125f061c9b43ebe4312441d3a0.diff

LOG: [MLIR] Move Presburger Math from FlatAffineConstraints to Presburger/IntegerPolyhedron

This patch factors out math functionality that is a subset of Presburger arithmetic and moves it from FlatAffineConstraints to Presburger/IntegerPolyhedron. This patch only moves some parts of the functionality planned to be moved, with subsequent patches moving more functionality. There are three main reasons for this:

1. This split makes the Presburger Library easier and more flexible to use
    across MLIR, by not depending on IR.
2. This split allows the Presburger library to be developed independently from
    Affine Analysis, with Affine Analysis using this library.
3. With more functionality being upstreamed to the Presburger Library, the
    mlir/Analysis directory will be cluttered with Presburger library components
    since they depend on math functionality from FlatAffineConstraints. Moving this
    functionality to the Presburger directory allows keeping the new functionality
    in the Presburger directory.

This patch is part of an ongoing effort to make the Presburger Library easier to use. The motivation for this effort is the feedback received at the LLVM conference from Mehdi and others.

Reviewed By: bondhugula

Differential Revision: https://reviews.llvm.org/D114674

Added: 
    mlir/include/mlir/Analysis/Presburger/IntegerPolyhedron.h
    mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp
    mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp

Modified: 
    mlir/include/mlir/Analysis/AffineStructures.h
    mlir/lib/Analysis/AffineStructures.cpp
    mlir/lib/Analysis/Presburger/CMakeLists.txt
    mlir/unittests/Analysis/AffineStructuresTest.cpp
    mlir/unittests/Analysis/Presburger/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Analysis/AffineStructures.h b/mlir/include/mlir/Analysis/AffineStructures.h
index 8235f03c470b3..9e7ffb125f7ec 100644
--- a/mlir/include/mlir/Analysis/AffineStructures.h
+++ b/mlir/include/mlir/Analysis/AffineStructures.h
@@ -13,6 +13,7 @@
 #ifndef MLIR_ANALYSIS_AFFINESTRUCTURES_H
 #define MLIR_ANALYSIS_AFFINESTRUCTURES_H
 
+#include "mlir/Analysis/Presburger/IntegerPolyhedron.h"
 #include "mlir/Analysis/Presburger/Matrix.h"
 #include "mlir/IR/AffineExpr.h"
 #include "mlir/IR/OpDefinition.h"
@@ -56,36 +57,29 @@ struct MutableAffineMap;
 /// that some floordiv combinations are converted to mod's by AffineExpr
 /// construction.
 ///
-class FlatAffineConstraints {
+class FlatAffineConstraints : public IntegerPolyhedron {
 public:
   /// All derived classes of FlatAffineConstraints.
   enum class Kind { FlatAffineConstraints, FlatAffineValueConstraints };
 
-  /// Kind of identifier (column).
-  enum IdKind { Dimension, Symbol, Local };
-
   /// Constructs a constraint system reserving memory for the specified number
   /// of constraints and identifiers.
   FlatAffineConstraints(unsigned numReservedInequalities,
                         unsigned numReservedEqualities,
                         unsigned numReservedCols, unsigned numDims,
                         unsigned numSymbols, unsigned numLocals)
-      : numIds(numDims + numSymbols + numLocals), numDims(numDims),
-        numSymbols(numSymbols),
-        equalities(0, numIds + 1, numReservedEqualities, numReservedCols),
-        inequalities(0, numIds + 1, numReservedInequalities, numReservedCols) {
-    assert(numReservedCols >= numIds + 1);
-  }
+      : IntegerPolyhedron(numReservedInequalities, numReservedEqualities,
+                          numReservedCols, numDims, numSymbols, numLocals) {}
 
   /// Constructs a constraint system with the specified number of
   /// dimensions and symbols.
   FlatAffineConstraints(unsigned numDims = 0, unsigned numSymbols = 0,
                         unsigned numLocals = 0)
-      : FlatAffineConstraints(/*numReservedInequalities=*/0,
-                              /*numReservedEqualities=*/0,
-                              /*numReservedCols=*/numDims + numSymbols +
-                                  numLocals + 1,
-                              numDims, numSymbols, numLocals) {}
+      : IntegerPolyhedron(/*numReservedInequalities=*/0,
+                          /*numReservedEqualities=*/0,
+                          /*numReservedCols=*/numDims + numSymbols + numLocals +
+                              1,
+                          numDims, numSymbols, numLocals) {}
 
   /// Return a system with no constraints, i.e., one which is satisfied by all
   /// points.
@@ -106,20 +100,6 @@ class FlatAffineConstraints {
 
   static bool classof(const FlatAffineConstraints *cst) { return true; }
 
-  /// Clears any existing data and reserves memory for the specified
-  /// constraints.
-  virtual void reset(unsigned numReservedInequalities,
-                     unsigned numReservedEqualities, unsigned numReservedCols,
-                     unsigned numDims, unsigned numSymbols,
-                     unsigned numLocals = 0);
-
-  void reset(unsigned numDims = 0, unsigned numSymbols = 0,
-             unsigned numLocals = 0);
-
-  /// Appends constraints from `other` into `this`. This is equivalent to an
-  /// intersection with no simplification of any sort attempted.
-  void append(const FlatAffineConstraints &other);
-
   /// Checks for emptiness by performing variable elimination on all
   /// identifiers, running the GCD test on each equality constraint, and
   /// checking for invalid constraints. Returns true if the GCD test fails for
@@ -177,41 +157,6 @@ class FlatAffineConstraints {
   // Clones this object.
   std::unique_ptr<FlatAffineConstraints> clone() const;
 
-  /// Returns the value at the specified equality row and column.
-  inline int64_t atEq(unsigned i, unsigned j) const { return equalities(i, j); }
-  inline int64_t &atEq(unsigned i, unsigned j) { return equalities(i, j); }
-
-  /// Returns the value at the specified inequality row and column.
-  inline int64_t atIneq(unsigned i, unsigned j) const {
-    return inequalities(i, j);
-  }
-  inline int64_t &atIneq(unsigned i, unsigned j) { return inequalities(i, j); }
-
-  /// Returns the number of columns in the constraint system.
-  inline unsigned getNumCols() const { return numIds + 1; }
-
-  inline unsigned getNumEqualities() const { return equalities.getNumRows(); }
-
-  inline unsigned getNumInequalities() const {
-    return inequalities.getNumRows();
-  }
-
-  inline unsigned getNumReservedEqualities() const {
-    return equalities.getNumReservedRows();
-  }
-
-  inline unsigned getNumReservedInequalities() const {
-    return inequalities.getNumReservedRows();
-  }
-
-  inline ArrayRef<int64_t> getEquality(unsigned idx) const {
-    return equalities.getRow(idx);
-  }
-
-  inline ArrayRef<int64_t> getInequality(unsigned idx) const {
-    return inequalities.getRow(idx);
-  }
-
   /// The type of bound: equal, lower bound or upper bound.
   enum BoundType { EQ, LB, UB };
 
@@ -246,11 +191,6 @@ class FlatAffineConstraints {
                       SmallVectorImpl<AffineMap> *lbMaps,
                       SmallVectorImpl<AffineMap> *ubMaps);
 
-  /// Adds an inequality (>= 0) from the coefficients specified in `inEq`.
-  void addInequality(ArrayRef<int64_t> inEq);
-  /// Adds an equality from the coefficients specified in `eq`.
-  void addEquality(ArrayRef<int64_t> eq);
-
   /// Adds a new local identifier as the floordiv of an affine function of other
   /// identifiers, the coefficients of which are provided in `dividend` and with
   /// respect to a positive constant `divisor`. Two constraints are added to the
@@ -258,27 +198,6 @@ class FlatAffineConstraints {
   /// q = dividend floordiv c    <=>   c*q <= dividend <= c*q + c - 1.
   void addLocalFloorDiv(ArrayRef<int64_t> dividend, int64_t divisor);
 
-  /// Swap the posA^th identifier with the posB^th identifier.
-  virtual void swapId(unsigned posA, unsigned posB);
-
-  /// Insert `num` identifiers of the specified kind at position `pos`.
-  /// Positions are relative to the kind of identifier. The coefficient columns
-  /// corresponding to the added identifiers are initialized to zero. Return the
-  /// absolute column position (i.e., not relative to the kind of identifier)
-  /// of the first added identifier.
-  unsigned insertDimId(unsigned pos, unsigned num = 1);
-  unsigned insertSymbolId(unsigned pos, unsigned num = 1);
-  unsigned insertLocalId(unsigned pos, unsigned num = 1);
-  virtual unsigned insertId(IdKind kind, unsigned pos, unsigned num = 1);
-
-  /// Append `num` identifiers of the specified kind after the last identifier.
-  /// of that kind. Return the position of the first appended column. The
-  /// coefficient columns corresponding to the added identifiers are initialized
-  /// to zero.
-  unsigned appendDimId(unsigned num = 1);
-  unsigned appendSymbolId(unsigned num = 1);
-  unsigned appendLocalId(unsigned num = 1);
-
   /// Composes an affine map whose dimensions and symbols match one to one with
   /// the dimensions and symbols of this FlatAffineConstraints. The results of
   /// the map `other` are added as the leading dimensions of this constraint
@@ -293,22 +212,6 @@ class FlatAffineConstraints {
   void projectOut(unsigned pos, unsigned num);
   inline void projectOut(unsigned pos) { return projectOut(pos, 1); }
 
-  /// Removes identifiers of the specified kind with the specified pos (or
-  /// within the specified range) from the system. The specified location is
-  /// relative to the first identifier of the specified kind.
-  void removeId(IdKind kind, unsigned pos);
-  void removeIdRange(IdKind kind, unsigned idStart, unsigned idLimit);
-
-  /// Removes the specified identifier from the system.
-  void removeId(unsigned pos);
-
-  void removeEquality(unsigned pos);
-  void removeInequality(unsigned pos);
-
-  /// Remove the (in)equalities at positions [start, end).
-  void removeEqualityRange(unsigned start, unsigned end);
-  void removeInequalityRange(unsigned start, unsigned end);
-
   /// Sets the `values.size()` identifiers starting at `po`s to the specified
   /// values and removes them.
   void setAndEliminate(unsigned pos, ArrayRef<int64_t> values);
@@ -347,17 +250,6 @@ class FlatAffineConstraints {
   ///    output = {0 <= d0 <= 6, 1 <= d1 <= 15}
   LogicalResult unionBoundingBox(const FlatAffineConstraints &other);
 
-  unsigned getNumConstraints() const {
-    return getNumInequalities() + getNumEqualities();
-  }
-  inline unsigned getNumIds() const { return numIds; }
-  inline unsigned getNumDimIds() const { return numDims; }
-  inline unsigned getNumSymbolIds() const { return numSymbols; }
-  inline unsigned getNumDimAndSymbolIds() const { return numDims + numSymbols; }
-  inline unsigned getNumLocalIds() const {
-    return numIds - numDims - numSymbols;
-  }
-
   /// Replaces the contents of this FlatAffineConstraints with `other`.
   virtual void clearAndCopyFrom(const FlatAffineConstraints &other);
 
@@ -453,19 +345,10 @@ class FlatAffineConstraints {
   /// match.
   void mergeLocalIds(FlatAffineConstraints &other);
 
-  /// Removes all equalities and inequalities.
-  void clearConstraints();
-
   void print(raw_ostream &os) const;
   void dump() const;
 
 protected:
-  /// Return the index at which the specified kind of id starts.
-  unsigned getIdKindOffset(IdKind kind) const;
-
-  /// Assert that `value` is at most the number of ids of the specified kind.
-  void assertAtMostNumIdKind(unsigned value, IdKind kind) const;
-
   /// Returns false if the fields corresponding to various identifier counts, or
   /// equality/inequality buffer sizes aren't consistent; true otherwise. This
   /// is meant to be used within an assert internally.
@@ -536,27 +419,6 @@ class FlatAffineConstraints {
   /// Normalized each constraints by the GCD of its coefficients.
   void normalizeConstraintsByGCD();
 
-  /// Removes identifiers in the column range [idStart, idLimit), and copies any
-  /// remaining valid data into place, updates member variables, and resizes
-  /// arrays as needed.
-  virtual void removeIdRange(unsigned idStart, unsigned idLimit);
-
-  /// Total number of identifiers.
-  unsigned numIds;
-
-  /// Number of identifiers corresponding to real dimensions.
-  unsigned numDims;
-
-  /// Number of identifiers corresponding to symbols (unknown but constant for
-  /// analysis).
-  unsigned numSymbols;
-
-  /// Coefficients of affine equalities (in == 0 form).
-  Matrix equalities;
-
-  /// Coefficients of affine inequalities (in >= 0 form).
-  Matrix inequalities;
-
   /// A parameter that controls detection of an unrealistic number of
   /// constraints. If the number of constraints is this many times the number of
   /// variables, we consider such a system out of line with the intended use

diff  --git a/mlir/include/mlir/Analysis/Presburger/IntegerPolyhedron.h b/mlir/include/mlir/Analysis/Presburger/IntegerPolyhedron.h
new file mode 100644
index 0000000000000..ad32d7a7aba9a
--- /dev/null
+++ b/mlir/include/mlir/Analysis/Presburger/IntegerPolyhedron.h
@@ -0,0 +1,219 @@
+//===- IntegerPolyhedron.h - MLIR IntegerPolyhedron Class -----*- C++ -*---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// A class to represent an integer polyhedron.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_ANALYSIS_PRESBURGER_INTEGERPOLYHEDRON_H
+#define MLIR_ANALYSIS_PRESBURGER_INTEGERPOLYHEDRON_H
+
+#include "mlir/Analysis/Presburger/Matrix.h"
+
+namespace mlir {
+
+/// An integer polyhedron is the set of solutions to a list of affine
+/// constraints over n integer-valued variables/identifiers. Affine constraints
+/// can be inequalities or equalities in the form:
+///
+/// Inequality: c_0*x_0 + c_1*x_1 + .... + c_{n-1}*x_{n-1} + c_n >= 0
+/// Equality  : c_0*x_0 + c_1*x_1 + .... + c_{n-1}*x_{n-1} + c_n == 0
+///
+/// where c_0, c_1, ..., c_n are integers.
+///
+/// Such a set corresponds to the set of integer points lying in a convex
+/// polyhedron. For example, consider the set: (x, y) : (1 <= x <= 7, x = 2y).
+/// This set contains the points (2, 1), (4, 2), and (6, 3).
+///
+/// The integer-valued variables are distinguished into 3 types of:
+///
+/// Dimension: Ordinary variables over which the set is represented.
+///
+/// Symbol: Symbol variables correspond to fixed but unknown values.
+/// Mathematically, an integer polyhedron with symbolic variables is like a
+/// family of integer polyhedra indexed by the symbolic variables.
+///
+/// Local: Local variables correspond to existentially quantified variables. For
+/// example, consider the set: (x) : (exists q : 1 <= x <= 7, x = 2q). An
+/// assignment to symbolic and dimension variables is valid if there exists some
+/// assignment to the local variable `q` satisfying these constraints. For this
+/// example, the set is equivalent to {2, 4, 6}. Mathematically, existential
+/// quantification can be thought of as the result of projection. In this
+/// example, `q` is existentially quantified. This can be thought of as the
+/// result of projecting out `q` from the previous example, i.e. we obtained {2,
+/// 4, 6} by projecting out the second dimension from {(2, 1), (4, 2), (6, 2)}.
+///
+class IntegerPolyhedron {
+public:
+  /// Kind of identifier (column).
+  enum IdKind { Dimension, Symbol, Local };
+
+  /// Constructs a constraint system reserving memory for the specified number
+  /// of constraints and identifiers.
+  IntegerPolyhedron(unsigned numReservedInequalities,
+                    unsigned numReservedEqualities, unsigned numReservedCols,
+                    unsigned numDims, unsigned numSymbols, unsigned numLocals)
+      : numIds(numDims + numSymbols + numLocals), numDims(numDims),
+        numSymbols(numSymbols),
+        equalities(0, numIds + 1, numReservedEqualities, numReservedCols),
+        inequalities(0, numIds + 1, numReservedInequalities, numReservedCols) {
+    assert(numReservedCols >= numIds + 1);
+  }
+
+  /// Constructs a constraint system with the specified number of
+  /// dimensions and symbols.
+  IntegerPolyhedron(unsigned numDims = 0, unsigned numSymbols = 0,
+                    unsigned numLocals = 0)
+      : IntegerPolyhedron(/*numReservedInequalities=*/0,
+                          /*numReservedEqualities=*/0,
+                          /*numReservedCols=*/numDims + numSymbols + numLocals +
+                              1,
+                          numDims, numSymbols, numLocals) {}
+
+  virtual ~IntegerPolyhedron() = default;
+
+  // Clones this object.
+  std::unique_ptr<IntegerPolyhedron> clone() const;
+
+  /// Clears any existing data and reserves memory for the specified
+  /// constraints.
+  virtual void reset(unsigned numReservedInequalities,
+                     unsigned numReservedEqualities, unsigned numReservedCols,
+                     unsigned numDims, unsigned numSymbols,
+                     unsigned numLocals = 0);
+
+  void reset(unsigned numDims = 0, unsigned numSymbols = 0,
+             unsigned numLocals = 0);
+
+  /// Appends constraints from `other` into `this`. This is equivalent to an
+  /// intersection with no simplification of any sort attempted.
+  void append(const IntegerPolyhedron &other);
+
+  /// Returns the value at the specified equality row and column.
+  inline int64_t atEq(unsigned i, unsigned j) const { return equalities(i, j); }
+  inline int64_t &atEq(unsigned i, unsigned j) { return equalities(i, j); }
+
+  /// Returns the value at the specified inequality row and column.
+  inline int64_t atIneq(unsigned i, unsigned j) const {
+    return inequalities(i, j);
+  }
+  inline int64_t &atIneq(unsigned i, unsigned j) { return inequalities(i, j); }
+
+  unsigned getNumConstraints() const {
+    return getNumInequalities() + getNumEqualities();
+  }
+  inline unsigned getNumIds() const { return numIds; }
+  inline unsigned getNumDimIds() const { return numDims; }
+  inline unsigned getNumSymbolIds() const { return numSymbols; }
+  inline unsigned getNumDimAndSymbolIds() const { return numDims + numSymbols; }
+  inline unsigned getNumLocalIds() const {
+    return numIds - numDims - numSymbols;
+  }
+
+  /// Returns the number of columns in the constraint system.
+  inline unsigned getNumCols() const { return numIds + 1; }
+
+  inline unsigned getNumEqualities() const { return equalities.getNumRows(); }
+
+  inline unsigned getNumInequalities() const {
+    return inequalities.getNumRows();
+  }
+
+  inline unsigned getNumReservedEqualities() const {
+    return equalities.getNumReservedRows();
+  }
+
+  inline unsigned getNumReservedInequalities() const {
+    return inequalities.getNumReservedRows();
+  }
+
+  inline ArrayRef<int64_t> getEquality(unsigned idx) const {
+    return equalities.getRow(idx);
+  }
+
+  inline ArrayRef<int64_t> getInequality(unsigned idx) const {
+    return inequalities.getRow(idx);
+  }
+
+  /// Insert `num` identifiers of the specified kind at position `pos`.
+  /// Positions are relative to the kind of identifier. The coefficient columns
+  /// corresponding to the added identifiers are initialized to zero. Return the
+  /// absolute column position (i.e., not relative to the kind of identifier)
+  /// of the first added identifier.
+  unsigned insertDimId(unsigned pos, unsigned num = 1);
+  unsigned insertSymbolId(unsigned pos, unsigned num = 1);
+  unsigned insertLocalId(unsigned pos, unsigned num = 1);
+  virtual unsigned insertId(IdKind kind, unsigned pos, unsigned num = 1);
+
+  /// Append `num` identifiers of the specified kind after the last identifier.
+  /// of that kind. Return the position of the first appended column. The
+  /// coefficient columns corresponding to the added identifiers are initialized
+  /// to zero.
+  unsigned appendDimId(unsigned num = 1);
+  unsigned appendSymbolId(unsigned num = 1);
+  unsigned appendLocalId(unsigned num = 1);
+
+  /// Adds an inequality (>= 0) from the coefficients specified in `inEq`.
+  void addInequality(ArrayRef<int64_t> inEq);
+  /// Adds an equality from the coefficients specified in `eq`.
+  void addEquality(ArrayRef<int64_t> eq);
+
+  /// Removes identifiers of the specified kind with the specified pos (or
+  /// within the specified range) from the system. The specified location is
+  /// relative to the first identifier of the specified kind.
+  void removeId(IdKind kind, unsigned pos);
+  void removeIdRange(IdKind kind, unsigned idStart, unsigned idLimit);
+
+  /// Removes the specified identifier from the system.
+  void removeId(unsigned pos);
+
+  void removeEquality(unsigned pos);
+  void removeInequality(unsigned pos);
+
+  /// Remove the (in)equalities at positions [start, end).
+  void removeEqualityRange(unsigned start, unsigned end);
+  void removeInequalityRange(unsigned start, unsigned end);
+
+  /// Swap the posA^th identifier with the posB^th identifier.
+  virtual void swapId(unsigned posA, unsigned posB);
+
+  /// Removes all equalities and inequalities.
+  void clearConstraints();
+
+protected:
+  /// Return the index at which the specified kind of id starts.
+  unsigned getIdKindOffset(IdKind kind) const;
+
+  /// Assert that `value` is at most the number of ids of the specified kind.
+  void assertAtMostNumIdKind(unsigned value, IdKind kind) const;
+
+  /// Removes identifiers in the column range [idStart, idLimit), and copies any
+  /// remaining valid data into place, updates member variables, and resizes
+  /// arrays as needed.
+  virtual void removeIdRange(unsigned idStart, unsigned idLimit);
+
+  /// Total number of identifiers.
+  unsigned numIds;
+
+  /// Number of identifiers corresponding to real dimensions.
+  unsigned numDims;
+
+  /// Number of identifiers corresponding to symbols (unknown but constant for
+  /// analysis).
+  unsigned numSymbols;
+
+  /// Coefficients of affine equalities (in == 0 form).
+  Matrix equalities;
+
+  /// Coefficients of affine inequalities (in >= 0 form).
+  Matrix inequalities;
+};
+
+} // namespace mlir
+
+#endif // MLIR_ANALYSIS_PRESBURGER_INTEGERPOLYHEDRON_H

diff  --git a/mlir/lib/Analysis/AffineStructures.cpp b/mlir/lib/Analysis/AffineStructures.cpp
index 34bd07ecc9e5d..8395a9dcf1a73 100644
--- a/mlir/lib/Analysis/AffineStructures.cpp
+++ b/mlir/lib/Analysis/AffineStructures.cpp
@@ -157,10 +157,11 @@ FlatAffineValueConstraints::clone() const {
 
 // Construct from an IntegerSet.
 FlatAffineConstraints::FlatAffineConstraints(IntegerSet set)
-    : numIds(set.getNumDims() + set.getNumSymbols()), numDims(set.getNumDims()),
-      numSymbols(set.getNumSymbols()),
-      equalities(0, numIds + 1, set.getNumEqualities(), numIds + 1),
-      inequalities(0, numIds + 1, set.getNumInequalities(), numIds + 1) {
+    : IntegerPolyhedron(set.getNumInequalities(), set.getNumEqualities(),
+                        set.getNumDims() + set.getNumSymbols() + 1,
+                        set.getNumDims(), set.getNumSymbols(),
+                        /*numLocals=*/0) {
+
   // Flatten expressions and add them to the constraint system.
   std::vector<SmallVector<int64_t, 8>> flatExprs;
   FlatAffineConstraints localVarCst;
@@ -232,18 +233,6 @@ FlatAffineValueConstraints::getHyperrectangular(ValueRange ivs, ValueRange lbs,
   return res;
 }
 
-void FlatAffineConstraints::reset(unsigned numReservedInequalities,
-                                  unsigned numReservedEqualities,
-                                  unsigned newNumReservedCols,
-                                  unsigned newNumDims, unsigned newNumSymbols,
-                                  unsigned newNumLocals) {
-  assert(newNumReservedCols >= newNumDims + newNumSymbols + newNumLocals + 1 &&
-         "minimum 1 column");
-  *this = FlatAffineConstraints(numReservedInequalities, numReservedEqualities,
-                                newNumReservedCols, newNumDims, newNumSymbols,
-                                newNumLocals);
-}
-
 void FlatAffineValueConstraints::reset(unsigned numReservedInequalities,
                                        unsigned numReservedEqualities,
                                        unsigned newNumReservedCols,
@@ -269,12 +258,6 @@ void FlatAffineValueConstraints::reset(
       newNumDims, newNumSymbols, newNumLocals, newVals);
 }
 
-void FlatAffineConstraints::reset(unsigned newNumDims, unsigned newNumSymbols,
-                                  unsigned newNumLocals) {
-  reset(0, 0, newNumDims + newNumSymbols + newNumLocals + 1, newNumDims,
-        newNumSymbols, newNumLocals);
-}
-
 void FlatAffineValueConstraints::reset(unsigned newNumDims,
                                        unsigned newNumSymbols,
                                        unsigned newNumLocals,
@@ -283,114 +266,28 @@ void FlatAffineValueConstraints::reset(unsigned newNumDims,
         newNumSymbols, newNumLocals, valArgs);
 }
 
-void FlatAffineConstraints::append(const FlatAffineConstraints &other) {
-  assert(other.getNumCols() == getNumCols());
-  assert(other.getNumDimIds() == getNumDimIds());
-  assert(other.getNumSymbolIds() == getNumSymbolIds());
-
-  inequalities.reserveRows(inequalities.getNumRows() +
-                           other.getNumInequalities());
-  equalities.reserveRows(equalities.getNumRows() + other.getNumEqualities());
-
-  for (unsigned r = 0, e = other.getNumInequalities(); r < e; r++) {
-    addInequality(other.getInequality(r));
-  }
-  for (unsigned r = 0, e = other.getNumEqualities(); r < e; r++) {
-    addEquality(other.getEquality(r));
-  }
-}
-
-unsigned FlatAffineConstraints::appendDimId(unsigned num) {
-  unsigned pos = getNumDimIds();
-  insertId(IdKind::Dimension, pos, num);
-  return pos;
-}
-
 unsigned FlatAffineValueConstraints::appendDimId(ValueRange vals) {
   unsigned pos = getNumDimIds();
   insertId(IdKind::Dimension, pos, vals);
   return pos;
 }
 
-unsigned FlatAffineConstraints::appendSymbolId(unsigned num) {
-  unsigned pos = getNumSymbolIds();
-  insertId(IdKind::Symbol, pos, num);
-  return pos;
-}
-
 unsigned FlatAffineValueConstraints::appendSymbolId(ValueRange vals) {
   unsigned pos = getNumSymbolIds();
   insertId(IdKind::Symbol, pos, vals);
   return pos;
 }
 
-unsigned FlatAffineConstraints::appendLocalId(unsigned num) {
-  unsigned pos = getNumLocalIds();
-  insertId(IdKind::Local, pos, num);
-  return pos;
-}
-
-unsigned FlatAffineConstraints::insertDimId(unsigned pos, unsigned num) {
-  return insertId(IdKind::Dimension, pos, num);
-}
-
 unsigned FlatAffineValueConstraints::insertDimId(unsigned pos,
                                                  ValueRange vals) {
   return insertId(IdKind::Dimension, pos, vals);
 }
 
-unsigned FlatAffineConstraints::insertSymbolId(unsigned pos, unsigned num) {
-  return insertId(IdKind::Symbol, pos, num);
-}
-
 unsigned FlatAffineValueConstraints::insertSymbolId(unsigned pos,
                                                     ValueRange vals) {
   return insertId(IdKind::Symbol, pos, vals);
 }
 
-unsigned FlatAffineConstraints::insertLocalId(unsigned pos, unsigned num) {
-  return insertId(IdKind::Local, pos, num);
-}
-
-unsigned FlatAffineConstraints::insertId(IdKind kind, unsigned pos,
-                                         unsigned num) {
-  assertAtMostNumIdKind(pos, kind);
-
-  unsigned absolutePos = getIdKindOffset(kind) + pos;
-  if (kind == IdKind::Dimension)
-    numDims += num;
-  else if (kind == IdKind::Symbol)
-    numSymbols += num;
-  numIds += num;
-
-  inequalities.insertColumns(absolutePos, num);
-  equalities.insertColumns(absolutePos, num);
-
-  return absolutePos;
-}
-
-void FlatAffineConstraints::assertAtMostNumIdKind(unsigned val,
-                                                  IdKind kind) const {
-  if (kind == IdKind::Dimension)
-    assert(val <= getNumDimIds());
-  else if (kind == IdKind::Symbol)
-    assert(val <= getNumSymbolIds());
-  else if (kind == IdKind::Local)
-    assert(val <= getNumLocalIds());
-  else
-    llvm_unreachable("IdKind expected to be Dimension, Symbol or Local!");
-}
-
-unsigned FlatAffineConstraints::getIdKindOffset(IdKind kind) const {
-  if (kind == IdKind::Dimension)
-    return 0;
-  if (kind == IdKind::Symbol)
-    return getNumDimIds();
-  if (kind == IdKind::Local)
-    return getNumDimAndSymbolIds();
-  llvm_unreachable("IdKind expected to be Dimension, Symbol or Local!");
-}
-
 unsigned FlatAffineValueConstraints::insertId(IdKind kind, unsigned pos,
                                               unsigned num) {
   unsigned absolutePos = FlatAffineConstraints::insertId(kind, pos, num);
@@ -420,17 +317,6 @@ bool FlatAffineValueConstraints::hasValues() const {
          }) != values.end();
 }
 
-void FlatAffineConstraints::removeId(IdKind kind, unsigned pos) {
-  removeIdRange(kind, pos, pos + 1);
-}
-
-void FlatAffineConstraints::removeIdRange(IdKind kind, unsigned idStart,
-                                          unsigned idLimit) {
-  assertAtMostNumIdKind(idLimit, kind);
-  removeIdRange(getIdKindOffset(kind) + idStart,
-                getIdKindOffset(kind) + idLimit);
-}
-
 /// Checks if two constraint systems are in the same space, i.e., if they are
 /// associated with the same set of identifiers, appearing in the same order.
 static bool areIdsAligned(const FlatAffineValueConstraints &a,
@@ -944,41 +830,6 @@ static void eliminateFromConstraint(FlatAffineConstraints *constraints,
   }
 }
 
-void FlatAffineConstraints::removeIdRange(unsigned idStart, unsigned idLimit) {
-  assert(idLimit < getNumCols() && "invalid id limit");
-
-  if (idStart >= idLimit)
-    return;
-
-  // We are going to be removing one or more identifiers from the range.
-  assert(idStart < numIds && "invalid idStart position");
-
-  // TODO: Make 'removeIdRange' a lambda called from here.
-  // Remove eliminated identifiers from the constraints..
-  equalities.removeColumns(idStart, idLimit - idStart);
-  inequalities.removeColumns(idStart, idLimit - idStart);
-
-  // Update members numDims, numSymbols and numIds.
-  unsigned numDimsEliminated = 0;
-  unsigned numLocalsEliminated = 0;
-  unsigned numColsEliminated = idLimit - idStart;
-  if (idStart < numDims) {
-    numDimsEliminated = std::min(numDims, idLimit) - idStart;
-  }
-  // Check how many local id's were removed. Note that our identifier order is
-  // [dims, symbols, locals]. Local id start at position numDims + numSymbols.
-  if (idLimit > numDims + numSymbols) {
-    numLocalsEliminated = std::min(
-        idLimit - std::max(idStart, numDims + numSymbols), getNumLocalIds());
-  }
-  unsigned numSymbolsEliminated =
-      numColsEliminated - numDimsEliminated - numLocalsEliminated;
-
-  numDims -= numDimsEliminated;
-  numSymbols -= numSymbolsEliminated;
-  numIds = numIds - numColsEliminated;
-}
-
 void FlatAffineValueConstraints::removeIdRange(unsigned idStart,
                                                unsigned idLimit) {
   FlatAffineConstraints::removeIdRange(idStart, idLimit);
@@ -2516,20 +2367,6 @@ LogicalResult FlatAffineValueConstraints::addSliceBounds(
   return success();
 }
 
-void FlatAffineConstraints::addEquality(ArrayRef<int64_t> eq) {
-  assert(eq.size() == getNumCols());
-  unsigned row = equalities.appendExtraRow();
-  for (unsigned i = 0, e = eq.size(); i < e; ++i)
-    equalities(row, i) = eq[i];
-}
-
-void FlatAffineConstraints::addInequality(ArrayRef<int64_t> inEq) {
-  assert(inEq.size() == getNumCols());
-  unsigned row = inequalities.appendExtraRow();
-  for (unsigned i = 0, e = inEq.size(); i < e; ++i)
-    inequalities(row, i) = inEq[i];
-}
-
 void FlatAffineConstraints::addBound(BoundType type, unsigned pos,
                                      int64_t value) {
   assert(pos < getNumCols());
@@ -2603,19 +2440,6 @@ bool FlatAffineValueConstraints::containsId(Value val) const {
   });
 }
 
-void FlatAffineConstraints::swapId(unsigned posA, unsigned posB) {
-  assert(posA < getNumIds() && "invalid position A");
-  assert(posB < getNumIds() && "invalid position B");
-
-  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));
-}
-
 void FlatAffineValueConstraints::swapId(unsigned posA, unsigned posB) {
   FlatAffineConstraints::swapId(posA, posB);
   std::swap(values[posA], values[posB]);
@@ -2637,27 +2461,6 @@ void FlatAffineValueConstraints::addBound(BoundType type, Value val,
   addBound(type, pos, value);
 }
 
-void FlatAffineConstraints::removeEquality(unsigned pos) {
-  equalities.removeRow(pos);
-}
-
-void FlatAffineConstraints::removeInequality(unsigned pos) {
-  inequalities.removeRow(pos);
-}
-
-void FlatAffineConstraints::removeEqualityRange(unsigned begin, unsigned end) {
-  if (begin >= end)
-    return;
-  equalities.removeRows(begin, end - begin);
-}
-
-void FlatAffineConstraints::removeInequalityRange(unsigned begin,
-                                                  unsigned end) {
-  if (begin >= end)
-    return;
-  inequalities.removeRows(begin, end - begin);
-}
-
 /// Finds an equality that equates the specified identifier to a constant.
 /// Returns the position of the equality row. If 'symbolic' is set to true,
 /// symbols are also treated like a constant, i.e., an affine function of the
@@ -3085,10 +2888,6 @@ void FlatAffineValueConstraints::clearAndCopyFrom(
   }
 }
 
-void FlatAffineConstraints::removeId(unsigned pos) {
-  removeIdRange(pos, pos + 1);
-}
-
 static std::pair<unsigned, unsigned>
 getNewNumDimsSymbols(unsigned pos, const FlatAffineConstraints &cst) {
   unsigned numDims = cst.getNumDimIds();
@@ -3371,11 +3170,6 @@ void FlatAffineValueConstraints::projectOut(Value val) {
   fourierMotzkinEliminate(pos);
 }
 
-void FlatAffineConstraints::clearConstraints() {
-  equalities.resizeVertically(0);
-  inequalities.resizeVertically(0);
-}
-
 namespace {
 
 enum BoundCmpResult { Greater, Less, Equal, Unknown };

diff  --git a/mlir/lib/Analysis/Presburger/CMakeLists.txt b/mlir/lib/Analysis/Presburger/CMakeLists.txt
index 73e2103c4c8e5..dd8c8d96d872c 100644
--- a/mlir/lib/Analysis/Presburger/CMakeLists.txt
+++ b/mlir/lib/Analysis/Presburger/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_mlir_library(MLIRPresburger
-  Simplex.cpp
+  IntegerPolyhedron.cpp
   Matrix.cpp
+  Simplex.cpp
 
   DEPENDS
   MLIRBuiltinLocationAttributesIncGen

diff  --git a/mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp b/mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp
new file mode 100644
index 0000000000000..5fc6533a98c14
--- /dev/null
+++ b/mlir/lib/Analysis/Presburger/IntegerPolyhedron.cpp
@@ -0,0 +1,220 @@
+//===- IntegerPolyhedron.cpp - MLIR IntegerPolyhedron Class ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// A class to represent an integer polyhedron.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Analysis/Presburger/IntegerPolyhedron.h"
+
+using namespace mlir;
+
+std::unique_ptr<IntegerPolyhedron> IntegerPolyhedron::clone() const {
+  return std::make_unique<IntegerPolyhedron>(*this);
+}
+
+void IntegerPolyhedron::reset(unsigned numReservedInequalities,
+                              unsigned numReservedEqualities,
+                              unsigned newNumReservedCols, unsigned newNumDims,
+                              unsigned newNumSymbols, unsigned newNumLocals) {
+  assert(newNumReservedCols >= newNumDims + newNumSymbols + newNumLocals + 1 &&
+         "minimum 1 column");
+  *this = IntegerPolyhedron(numReservedInequalities, numReservedEqualities,
+                            newNumReservedCols, newNumDims, newNumSymbols,
+                            newNumLocals);
+}
+
+void IntegerPolyhedron::reset(unsigned newNumDims, unsigned newNumSymbols,
+                              unsigned newNumLocals) {
+  reset(0, 0, newNumDims + newNumSymbols + newNumLocals + 1, newNumDims,
+        newNumSymbols, newNumLocals);
+}
+
+void IntegerPolyhedron::append(const IntegerPolyhedron &other) {
+  assert(other.getNumCols() == getNumCols());
+  assert(other.getNumDimIds() == getNumDimIds());
+  assert(other.getNumSymbolIds() == getNumSymbolIds());
+
+  inequalities.reserveRows(inequalities.getNumRows() +
+                           other.getNumInequalities());
+  equalities.reserveRows(equalities.getNumRows() + other.getNumEqualities());
+
+  for (unsigned r = 0, e = other.getNumInequalities(); r < e; r++) {
+    addInequality(other.getInequality(r));
+  }
+  for (unsigned r = 0, e = other.getNumEqualities(); r < e; r++) {
+    addEquality(other.getEquality(r));
+  }
+}
+
+unsigned IntegerPolyhedron::insertDimId(unsigned pos, unsigned num) {
+  return insertId(IdKind::Dimension, pos, num);
+}
+
+unsigned IntegerPolyhedron::insertSymbolId(unsigned pos, unsigned num) {
+  return insertId(IdKind::Symbol, pos, num);
+}
+
+unsigned IntegerPolyhedron::insertLocalId(unsigned pos, unsigned num) {
+  return insertId(IdKind::Local, pos, num);
+}
+
+unsigned IntegerPolyhedron::insertId(IdKind kind, unsigned pos, unsigned num) {
+  assertAtMostNumIdKind(pos, kind);
+
+  unsigned absolutePos = getIdKindOffset(kind) + pos;
+  if (kind == IdKind::Dimension)
+    numDims += num;
+  else if (kind == IdKind::Symbol)
+    numSymbols += num;
+  numIds += num;
+
+  inequalities.insertColumns(absolutePos, num);
+  equalities.insertColumns(absolutePos, num);
+
+  return absolutePos;
+}
+
+unsigned IntegerPolyhedron::appendDimId(unsigned num) {
+  unsigned pos = getNumDimIds();
+  insertId(IdKind::Dimension, pos, num);
+  return pos;
+}
+
+unsigned IntegerPolyhedron::appendSymbolId(unsigned num) {
+  unsigned pos = getNumSymbolIds();
+  insertId(IdKind::Symbol, pos, num);
+  return pos;
+}
+
+unsigned IntegerPolyhedron::appendLocalId(unsigned num) {
+  unsigned pos = getNumLocalIds();
+  insertId(IdKind::Local, pos, num);
+  return pos;
+}
+
+void IntegerPolyhedron::addEquality(ArrayRef<int64_t> eq) {
+  assert(eq.size() == getNumCols());
+  unsigned row = equalities.appendExtraRow();
+  for (unsigned i = 0, e = eq.size(); i < e; ++i)
+    equalities(row, i) = eq[i];
+}
+
+void IntegerPolyhedron::addInequality(ArrayRef<int64_t> inEq) {
+  assert(inEq.size() == getNumCols());
+  unsigned row = inequalities.appendExtraRow();
+  for (unsigned i = 0, e = inEq.size(); i < e; ++i)
+    inequalities(row, i) = inEq[i];
+}
+
+void IntegerPolyhedron::removeId(IdKind kind, unsigned pos) {
+  removeIdRange(kind, pos, pos + 1);
+}
+
+void IntegerPolyhedron::removeId(unsigned pos) { removeIdRange(pos, pos + 1); }
+
+void IntegerPolyhedron::removeIdRange(IdKind kind, unsigned idStart,
+                                      unsigned idLimit) {
+  assertAtMostNumIdKind(idLimit, kind);
+  removeIdRange(getIdKindOffset(kind) + idStart,
+                getIdKindOffset(kind) + idLimit);
+}
+
+void IntegerPolyhedron::removeIdRange(unsigned idStart, unsigned idLimit) {
+  assert(idLimit < getNumCols() && "invalid id limit");
+
+  if (idStart >= idLimit)
+    return;
+
+  // We are going to be removing one or more identifiers from the range.
+  assert(idStart < numIds && "invalid idStart position");
+
+  // TODO: Make 'removeIdRange' a lambda called from here.
+  // Remove eliminated identifiers from the constraints..
+  equalities.removeColumns(idStart, idLimit - idStart);
+  inequalities.removeColumns(idStart, idLimit - idStart);
+
+  // Update members numDims, numSymbols and numIds.
+  unsigned numDimsEliminated = 0;
+  unsigned numLocalsEliminated = 0;
+  unsigned numColsEliminated = idLimit - idStart;
+  if (idStart < numDims) {
+    numDimsEliminated = std::min(numDims, idLimit) - idStart;
+  }
+  // Check how many local id's were removed. Note that our identifier order is
+  // [dims, symbols, locals]. Local id start at position numDims + numSymbols.
+  if (idLimit > numDims + numSymbols) {
+    numLocalsEliminated = std::min(
+        idLimit - std::max(idStart, numDims + numSymbols), getNumLocalIds());
+  }
+  unsigned numSymbolsEliminated =
+      numColsEliminated - numDimsEliminated - numLocalsEliminated;
+
+  numDims -= numDimsEliminated;
+  numSymbols -= numSymbolsEliminated;
+  numIds = numIds - numColsEliminated;
+}
+
+void IntegerPolyhedron::removeEquality(unsigned pos) {
+  equalities.removeRow(pos);
+}
+
+void IntegerPolyhedron::removeInequality(unsigned pos) {
+  inequalities.removeRow(pos);
+}
+
+void IntegerPolyhedron::removeEqualityRange(unsigned begin, unsigned end) {
+  if (begin >= end)
+    return;
+  equalities.removeRows(begin, end - begin);
+}
+
+void IntegerPolyhedron::removeInequalityRange(unsigned begin, unsigned end) {
+  if (begin >= end)
+    return;
+  inequalities.removeRows(begin, end - begin);
+}
+
+void IntegerPolyhedron::swapId(unsigned posA, unsigned posB) {
+  assert(posA < getNumIds() && "invalid position A");
+  assert(posB < getNumIds() && "invalid position B");
+
+  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));
+}
+
+unsigned IntegerPolyhedron::getIdKindOffset(IdKind kind) const {
+  if (kind == IdKind::Dimension)
+    return 0;
+  if (kind == IdKind::Symbol)
+    return getNumDimIds();
+  if (kind == IdKind::Local)
+    return getNumDimAndSymbolIds();
+  llvm_unreachable("IdKind expected to be Dimension, Symbol or Local!");
+}
+
+void IntegerPolyhedron::assertAtMostNumIdKind(unsigned val, IdKind kind) const {
+  if (kind == IdKind::Dimension)
+    assert(val <= getNumDimIds());
+  else if (kind == IdKind::Symbol)
+    assert(val <= getNumSymbolIds());
+  else if (kind == IdKind::Local)
+    assert(val <= getNumLocalIds());
+  else
+    llvm_unreachable("IdKind expected to be Dimension, Symbol or Local!");
+}
+
+void IntegerPolyhedron::clearConstraints() {
+  equalities.resizeVertically(0);
+  inequalities.resizeVertically(0);
+}

diff  --git a/mlir/unittests/Analysis/AffineStructuresTest.cpp b/mlir/unittests/Analysis/AffineStructuresTest.cpp
index 0d6c0f09fb5b8..ae32d8a729ae2 100644
--- a/mlir/unittests/Analysis/AffineStructuresTest.cpp
+++ b/mlir/unittests/Analysis/AffineStructuresTest.cpp
@@ -591,58 +591,6 @@ TEST(FlatAffineConstraintsTest, addConstantLowerBound) {
   EXPECT_EQ(fac.atIneq(1, 2), 2);
 }
 
-TEST(FlatAffineConstraintsTest, removeInequality) {
-  FlatAffineConstraints fac =
-      makeFACFromConstraints(1, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}}, {});
-
-  fac.removeInequalityRange(0, 0);
-  EXPECT_EQ(fac.getNumInequalities(), 5u);
-
-  fac.removeInequalityRange(1, 3);
-  EXPECT_EQ(fac.getNumInequalities(), 3u);
-  EXPECT_THAT(fac.getInequality(0), ElementsAre(0, 0));
-  EXPECT_THAT(fac.getInequality(1), ElementsAre(3, 3));
-  EXPECT_THAT(fac.getInequality(2), ElementsAre(4, 4));
-
-  fac.removeInequality(1);
-  EXPECT_EQ(fac.getNumInequalities(), 2u);
-  EXPECT_THAT(fac.getInequality(0), ElementsAre(0, 0));
-  EXPECT_THAT(fac.getInequality(1), ElementsAre(4, 4));
-}
-
-TEST(FlatAffineConstraintsTest, removeEquality) {
-  FlatAffineConstraints fac =
-      makeFACFromConstraints(1, {}, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}});
-
-  fac.removeEqualityRange(0, 0);
-  EXPECT_EQ(fac.getNumEqualities(), 5u);
-
-  fac.removeEqualityRange(1, 3);
-  EXPECT_EQ(fac.getNumEqualities(), 3u);
-  EXPECT_THAT(fac.getEquality(0), ElementsAre(0, 0));
-  EXPECT_THAT(fac.getEquality(1), ElementsAre(3, 3));
-  EXPECT_THAT(fac.getEquality(2), ElementsAre(4, 4));
-
-  fac.removeEquality(1);
-  EXPECT_EQ(fac.getNumEqualities(), 2u);
-  EXPECT_THAT(fac.getEquality(0), ElementsAre(0, 0));
-  EXPECT_THAT(fac.getEquality(1), ElementsAre(4, 4));
-}
-
-TEST(FlatAffineConstraintsTest, clearConstraints) {
-  FlatAffineConstraints fac = makeFACFromConstraints(1, {}, {});
-
-  fac.addInequality({1, 0});
-  EXPECT_EQ(fac.atIneq(0, 0), 1);
-  EXPECT_EQ(fac.atIneq(0, 1), 0);
-
-  fac.clearConstraints();
-
-  fac.addInequality({1, 0});
-  EXPECT_EQ(fac.atIneq(0, 0), 1);
-  EXPECT_EQ(fac.atIneq(0, 1), 0);
-}
-
 /// Check if the expected division representation of local variables matches the
 /// computed representation. The expected division representation is given as
 /// a vector of expressions set in `expectedDividends` and the corressponding
@@ -723,24 +671,6 @@ TEST(FlatAffineConstraintsTest, computeLocalReprRecursive) {
   checkDivisionRepresentation(fac, divisions, denoms);
 }
 
-TEST(FlatAffineConstraintsTest, removeIdRange) {
-  FlatAffineConstraints fac(3, 2, 1);
-
-  fac.addInequality({10, 11, 12, 20, 21, 30, 40});
-  fac.removeId(FlatAffineConstraints::IdKind::Symbol, 1);
-  EXPECT_THAT(fac.getInequality(0),
-              testing::ElementsAre(10, 11, 12, 20, 30, 40));
-
-  fac.removeIdRange(FlatAffineConstraints::IdKind::Dimension, 0, 2);
-  EXPECT_THAT(fac.getInequality(0), testing::ElementsAre(12, 20, 30, 40));
-
-  fac.removeIdRange(FlatAffineConstraints::IdKind::Local, 1, 1);
-  EXPECT_THAT(fac.getInequality(0), testing::ElementsAre(12, 20, 30, 40));
-
-  fac.removeIdRange(FlatAffineConstraints::IdKind::Local, 0, 1);
-  EXPECT_THAT(fac.getInequality(0), testing::ElementsAre(12, 20, 40));
-}
-
 TEST(FlatAffineConstraintsTest, simplifyLocalsTest) {
   // (x) : (exists y: 2x + y = 1 and y = 2).
   FlatAffineConstraints fac(1, 0, 1);

diff  --git a/mlir/unittests/Analysis/Presburger/CMakeLists.txt b/mlir/unittests/Analysis/Presburger/CMakeLists.txt
index 818dc934c1004..fd4957a93a860 100644
--- a/mlir/unittests/Analysis/Presburger/CMakeLists.txt
+++ b/mlir/unittests/Analysis/Presburger/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_mlir_unittest(MLIRPresburgerTests
+  IntegerPolyhedronTest.cpp
   MatrixTest.cpp
   SimplexTest.cpp
   ../AffineStructuresParser.cpp

diff  --git a/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp
new file mode 100644
index 0000000000000..1598f051678f1
--- /dev/null
+++ b/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp
@@ -0,0 +1,103 @@
+//===- IntegerPolyhedron.cpp - Tests for IntegerPolyhedron class ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Analysis/Presburger/IntegerPolyhedron.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace mlir {
+
+using testing::ElementsAre;
+
+/// Construct a IntegerPolyhedron from a set of inequality and
+/// equality constraints.
+static IntegerPolyhedron
+makeSetFromConstraints(unsigned ids, ArrayRef<SmallVector<int64_t, 4>> ineqs,
+                       ArrayRef<SmallVector<int64_t, 4>> eqs,
+                       unsigned syms = 0) {
+  IntegerPolyhedron set(ineqs.size(), eqs.size(), ids + 1, ids - syms, syms,
+                        /*numLocals=*/0);
+  for (const auto &eq : eqs)
+    set.addEquality(eq);
+  for (const auto &ineq : ineqs)
+    set.addInequality(ineq);
+  return set;
+}
+
+TEST(IntegerPolyhedronTest, removeInequality) {
+  IntegerPolyhedron set =
+      makeSetFromConstraints(1, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}}, {});
+
+  set.removeInequalityRange(0, 0);
+  EXPECT_EQ(set.getNumInequalities(), 5u);
+
+  set.removeInequalityRange(1, 3);
+  EXPECT_EQ(set.getNumInequalities(), 3u);
+  EXPECT_THAT(set.getInequality(0), ElementsAre(0, 0));
+  EXPECT_THAT(set.getInequality(1), ElementsAre(3, 3));
+  EXPECT_THAT(set.getInequality(2), ElementsAre(4, 4));
+
+  set.removeInequality(1);
+  EXPECT_EQ(set.getNumInequalities(), 2u);
+  EXPECT_THAT(set.getInequality(0), ElementsAre(0, 0));
+  EXPECT_THAT(set.getInequality(1), ElementsAre(4, 4));
+}
+
+TEST(IntegerPolyhedronTest, removeEquality) {
+  IntegerPolyhedron set =
+      makeSetFromConstraints(1, {}, {{0, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}});
+
+  set.removeEqualityRange(0, 0);
+  EXPECT_EQ(set.getNumEqualities(), 5u);
+
+  set.removeEqualityRange(1, 3);
+  EXPECT_EQ(set.getNumEqualities(), 3u);
+  EXPECT_THAT(set.getEquality(0), ElementsAre(0, 0));
+  EXPECT_THAT(set.getEquality(1), ElementsAre(3, 3));
+  EXPECT_THAT(set.getEquality(2), ElementsAre(4, 4));
+
+  set.removeEquality(1);
+  EXPECT_EQ(set.getNumEqualities(), 2u);
+  EXPECT_THAT(set.getEquality(0), ElementsAre(0, 0));
+  EXPECT_THAT(set.getEquality(1), ElementsAre(4, 4));
+}
+
+TEST(IntegerPolyhedronTest, clearConstraints) {
+  IntegerPolyhedron set = makeSetFromConstraints(1, {}, {});
+
+  set.addInequality({1, 0});
+  EXPECT_EQ(set.atIneq(0, 0), 1);
+  EXPECT_EQ(set.atIneq(0, 1), 0);
+
+  set.clearConstraints();
+
+  set.addInequality({1, 0});
+  EXPECT_EQ(set.atIneq(0, 0), 1);
+  EXPECT_EQ(set.atIneq(0, 1), 0);
+}
+
+TEST(IntegerPolyhedronTest, removeIdRange) {
+  IntegerPolyhedron set(3, 2, 1);
+
+  set.addInequality({10, 11, 12, 20, 21, 30, 40});
+  set.removeId(IntegerPolyhedron::IdKind::Symbol, 1);
+  EXPECT_THAT(set.getInequality(0),
+              testing::ElementsAre(10, 11, 12, 20, 30, 40));
+
+  set.removeIdRange(IntegerPolyhedron::IdKind::Dimension, 0, 2);
+  EXPECT_THAT(set.getInequality(0), testing::ElementsAre(12, 20, 30, 40));
+
+  set.removeIdRange(IntegerPolyhedron::IdKind::Local, 1, 1);
+  EXPECT_THAT(set.getInequality(0), testing::ElementsAre(12, 20, 30, 40));
+
+  set.removeIdRange(IntegerPolyhedron::IdKind::Local, 0, 1);
+  EXPECT_THAT(set.getInequality(0), testing::ElementsAre(12, 20, 40));
+}
+
+} // namespace mlir


        


More information about the Mlir-commits mailing list