[Mlir-commits] [mlir] 4fa96b7 - [MLIR] Simplex: split some basic functionality out into a SimplexBase class

Arjun P llvmlistbot at llvm.org
Sun Dec 19 08:54:45 PST 2021


Author: Arjun P
Date: 2021-12-19T22:24:40+05:30
New Revision: 4fa96b7eca73b6b235e22f18371dba8c20ed715a

URL: https://github.com/llvm/llvm-project/commit/4fa96b7eca73b6b235e22f18371dba8c20ed715a
DIFF: https://github.com/llvm/llvm-project/commit/4fa96b7eca73b6b235e22f18371dba8c20ed715a.diff

LOG: [MLIR] Simplex: split some basic functionality out into a SimplexBase class

This is a purely mechanical patch moving some functionality out from the
`Simplex` class out into a `SimplexBase` class. This pavees the way for
a future patch adding support for lexicographic optimization with a class
`LexSimplex`, which will inherit from `SimplexBase`. Inheriting directly
from `Simplex` would bring many additional functions that would not work in
`LexSimplex` because it operates slighty differently from `Simplex`. So We
split out only the basic functionality it needs to inherit into `SimplexBase`.

Reviewed By: Groverkss

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

Added: 
    

Modified: 
    mlir/include/mlir/Analysis/Presburger/Simplex.h
    mlir/lib/Analysis/Presburger/Simplex.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Analysis/Presburger/Simplex.h b/mlir/include/mlir/Analysis/Presburger/Simplex.h
index 87217cd7e13c3..a04f0b0a485b6 100644
--- a/mlir/include/mlir/Analysis/Presburger/Simplex.h
+++ b/mlir/include/mlir/Analysis/Presburger/Simplex.h
@@ -29,7 +29,7 @@ namespace mlir {
 
 class GBRSimplex;
 
-/// This class implements a version of the Simplex and Generalized Basis
+/// The Simplex class implements a version of the Simplex and Generalized Basis
 /// Reduction algorithms, which can perform analysis of integer sets with affine
 /// inequalities and equalities. A Simplex can be constructed
 /// by specifying the dimensionality of the set. It supports adding affine
@@ -41,8 +41,8 @@ class GBRSimplex;
 /// set further after adding the non-redundant constraints. Simplex can also be
 /// constructed from a FlatAffineConstraints object.
 ///
-/// The implementation of this Simplex class, other than the functionality
-/// for sampling, is based on the paper
+/// The implementation of the Simplex and SimplexBase classes, other than the
+/// functionality for sampling, is based on the paper
 /// "Simplify: A Theorem Prover for Program Checking"
 /// by D. Detlefs, G. Nelson, J. B. Saxe.
 ///
@@ -134,13 +134,19 @@ class GBRSimplex;
 ///
 /// Finding an integer sample is done with the Generalized Basis Reduction
 /// algorithm. See the documentation for findIntegerSample and reduceBasis.
-class Simplex {
+///
+/// The SimplexBase class contains some basic functionality. In the future,
+/// lexicographic optimization will be supported by a class inheriting from
+/// SimplexBase. Functionality that will not supported by that class is placed
+/// in `Simplex`.
+
+class SimplexBase {
 public:
   enum class Direction { Up, Down };
 
-  Simplex() = delete;
-  explicit Simplex(unsigned nVar);
-  explicit Simplex(const FlatAffineConstraints &constraints);
+  SimplexBase() = delete;
+  explicit SimplexBase(unsigned nVar);
+  explicit SimplexBase(const FlatAffineConstraints &constraints);
 
   /// Returns true if the tableau is empty (has conflicting constraints),
   /// false otherwise.
@@ -177,50 +183,6 @@ class Simplex {
   /// Add all the constraints from the given FlatAffineConstraints.
   void intersectFlatAffineConstraints(const FlatAffineConstraints &fac);
 
-  /// Compute the maximum or minimum value of the given row, depending on
-  /// direction. The specified row is never pivoted. On return, the row may
-  /// have a negative sample value if the direction is down.
-  ///
-  /// Returns a Fraction denoting the optimum, or a null value if no optimum
-  /// exists, i.e., if the expression is unbounded in this direction.
-  Optional<Fraction> computeRowOptimum(Direction direction, unsigned row);
-
-  /// Compute the maximum or minimum value of the given expression, depending on
-  /// direction. Should not be called when the Simplex is empty.
-  ///
-  /// Returns a Fraction denoting the optimum, or a null value if no optimum
-  /// exists, i.e., if the expression is unbounded in this direction.
-  Optional<Fraction> computeOptimum(Direction direction,
-                                    ArrayRef<int64_t> coeffs);
-
-  /// Returns whether the perpendicular of the specified constraint
-  /// is a direction along which the polytope is bounded.
-  bool isBoundedAlongConstraint(unsigned constraintIndex);
-
-  /// Returns whether the specified constraint has been marked as redundant.
-  /// Constraints are numbered from 0 starting at the first added inequality.
-  /// Equalities are added as a pair of inequalities and so correspond to two
-  /// inequalities with successive indices.
-  bool isMarkedRedundant(unsigned constraintIndex) const;
-
-  /// Finds a subset of constraints that is redundant, i.e., such that
-  /// the set of solutions does not change if these constraints are removed.
-  /// Marks these constraints as redundant. Whether a specific constraint has
-  /// been marked redundant can be queried using isMarkedRedundant.
-  void detectRedundant();
-
-  /// Returns a (min, max) pair denoting the minimum and maximum integer values
-  /// of the given expression.
-  std::pair<int64_t, int64_t> computeIntegerBounds(ArrayRef<int64_t> coeffs);
-
-  /// Returns true if the polytope is unbounded, i.e., extends to infinity in
-  /// some direction. Otherwise, returns false.
-  bool isUnbounded();
-
-  /// Make a tableau to represent a pair of points in the given tableaus, one in
-  /// tableau A and one in B.
-  static Simplex makeProduct(const Simplex &a, const Simplex &b);
-
   /// Returns a rational sample point. This should not be called when Simplex is
   /// empty.
   SmallVector<Fraction, 8> getRationalSample() const;
@@ -229,27 +191,11 @@ class Simplex {
   /// None.
   Optional<SmallVector<int64_t, 8>> getSamplePointIfIntegral() const;
 
-  /// Returns an integer sample point if one exists, or None
-  /// otherwise. This should only be called for bounded sets.
-  Optional<SmallVector<int64_t, 8>> findIntegerSample();
-
   /// Print the tableau's internal state.
   void print(raw_ostream &os) const;
   void dump() const;
 
-  /// Check if the specified inequality already holds in the polytope.
-  bool isRedundantInequality(ArrayRef<int64_t> coeffs);
-
-  /// Check if the specified equality already holds in the polytope.
-  bool isRedundantEquality(ArrayRef<int64_t> coeffs);
-
-  /// Returns true if this Simplex's polytope is a rational subset of `fac`.
-  /// Otherwise, returns false.
-  bool isRationalSubsetOf(const FlatAffineConstraints &fac);
-
-private:
-  friend class GBRSimplex;
-
+protected:
   enum class Orientation { Row, Column };
 
   /// An Unknown is either a variable or a constraint. It is always associated
@@ -324,20 +270,6 @@ class Simplex {
   /// sample value, failure otherwise.
   LogicalResult restoreRow(Unknown &u);
 
-  /// Compute the maximum or minimum of the specified Unknown, depending on
-  /// direction. The specified unknown may be pivoted. If the unknown is
-  /// restricted, it will have a non-negative sample value on return.
-  /// Should not be called if the Simplex is empty.
-  ///
-  /// Returns a Fraction denoting the optimum, or a null value if no optimum
-  /// exists, i.e., if the expression is unbounded in this direction.
-  Optional<Fraction> computeOptimum(Direction direction, Unknown &u);
-
-  /// Mark the specified unknown redundant. This operation is added to the undo
-  /// log and will be undone by rollbacks. The specified unknown must be in row
-  /// orientation.
-  void markRowRedundant(Unknown &u);
-
   /// Enum to denote operations that need to be undone during rollback.
   enum class UndoLogEntry {
     RemoveLastConstraint,
@@ -360,10 +292,6 @@ class Simplex {
   Optional<unsigned> findPivotRow(Optional<unsigned> skipRow,
                                   Direction direction, unsigned col) const;
 
-  /// Reduce the given basis, starting at the specified level, using general
-  /// basis reduction.
-  void reduceBasis(Matrix &basis, unsigned level);
-
   /// The number of rows in the tableau.
   unsigned nRow;
 
@@ -398,6 +326,93 @@ class Simplex {
   SmallVector<Unknown, 8> con, var;
 };
 
+class Simplex : public SimplexBase {
+public:
+  Simplex() = delete;
+  explicit Simplex(unsigned nVar) : SimplexBase(nVar) {}
+  explicit Simplex(const FlatAffineConstraints &constraints)
+      : SimplexBase(constraints) {}
+
+  /// Compute the maximum or minimum value of the given row, depending on
+  /// direction. The specified row is never pivoted. On return, the row may
+  /// have a negative sample value if the direction is down.
+  ///
+  /// Returns a Fraction denoting the optimum, or a null value if no optimum
+  /// exists, i.e., if the expression is unbounded in this direction.
+  Optional<Fraction> computeRowOptimum(Direction direction, unsigned row);
+
+  /// Compute the maximum or minimum value of the given expression, depending on
+  /// direction. Should not be called when the Simplex is empty.
+  ///
+  /// Returns a Fraction denoting the optimum, or a null value if no optimum
+  /// exists, i.e., if the expression is unbounded in this direction.
+  Optional<Fraction> computeOptimum(Direction direction,
+                                    ArrayRef<int64_t> coeffs);
+
+  /// Returns whether the perpendicular of the specified constraint is a
+  /// is a direction along which the polytope is bounded.
+  bool isBoundedAlongConstraint(unsigned constraintIndex);
+
+  /// Returns whether the specified constraint has been marked as redundant.
+  /// Constraints are numbered from 0 starting at the first added inequality.
+  /// Equalities are added as a pair of inequalities and so correspond to two
+  /// inequalities with successive indices.
+  bool isMarkedRedundant(unsigned constraintIndex) const;
+
+  /// Finds a subset of constraints that is redundant, i.e., such that
+  /// the set of solutions does not change if these constraints are removed.
+  /// Marks these constraints as redundant. Whether a specific constraint has
+  /// been marked redundant can be queried using isMarkedRedundant.
+  void detectRedundant();
+
+  /// Returns a (min, max) pair denoting the minimum and maximum integer values
+  /// of the given expression.
+  std::pair<int64_t, int64_t> computeIntegerBounds(ArrayRef<int64_t> coeffs);
+
+  /// Returns true if the polytope is unbounded, i.e., extends to infinity in
+  /// some direction. Otherwise, returns false.
+  bool isUnbounded();
+
+  /// Make a tableau to represent a pair of points in the given tableaus, one in
+  /// tableau A and one in B.
+  static Simplex makeProduct(const Simplex &a, const Simplex &b);
+
+  /// Returns an integer sample point if one exists, or None
+  /// otherwise. This should only be called for bounded sets.
+  Optional<SmallVector<int64_t, 8>> findIntegerSample();
+
+  /// Check if the specified inequality already holds in the polytope.
+  bool isRedundantInequality(ArrayRef<int64_t> coeffs);
+
+  /// Check if the specified equality already holds in the polytope.
+  bool isRedundantEquality(ArrayRef<int64_t> coeffs);
+
+  /// Returns true if this Simplex's polytope is a rational subset of `fac`.
+  /// Otherwise, returns false.
+  bool isRationalSubsetOf(const FlatAffineConstraints &fac);
+
+private:
+  friend class GBRSimplex;
+
+  /// Compute the maximum or minimum of the specified Unknown, depending on
+  /// direction. The specified unknown may be pivoted. If the unknown is
+  /// restricted, it will have a non-negative sample value on return.
+  /// Should not be called if the Simplex is empty.
+  ///
+  /// Returns a Fraction denoting the optimum, or a null value if no optimum
+  /// exists, i.e., if the expression is unbounded in this direction.
+  Optional<Fraction> computeOptimum(Direction direction, Unknown &u);
+
+  /// Mark the specified unknown redundant. This operation is added to the undo
+  /// log and will be undone by rollbacks. The specified unknown must be in row
+  /// orientation.
+  void markRowRedundant(Unknown &u);
+
+  /// Reduce the given basis, starting at the specified level, using general
+  /// basis reduction.
+  void reduceBasis(Matrix &basis, unsigned level);
+};
+
 } // namespace mlir
 
 #endif // MLIR_ANALYSIS_PRESBURGER_SIMPLEX_H

diff  --git a/mlir/lib/Analysis/Presburger/Simplex.cpp b/mlir/lib/Analysis/Presburger/Simplex.cpp
index a52712aa44b4e..ed3232d6fc5b8 100644
--- a/mlir/lib/Analysis/Presburger/Simplex.cpp
+++ b/mlir/lib/Analysis/Presburger/Simplex.cpp
@@ -17,7 +17,7 @@ using Direction = Simplex::Direction;
 const int nullIndex = std::numeric_limits<int>::max();
 
 /// Construct a Simplex object with `nVar` variables.
-Simplex::Simplex(unsigned nVar)
+SimplexBase::SimplexBase(unsigned nVar)
     : nRow(0), nCol(2), nRedundant(0), tableau(0, 2 + nVar), empty(false) {
   colUnknown.push_back(nullIndex);
   colUnknown.push_back(nullIndex);
@@ -28,8 +28,8 @@ Simplex::Simplex(unsigned nVar)
   }
 }
 
-Simplex::Simplex(const FlatAffineConstraints &constraints)
-    : Simplex(constraints.getNumIds()) {
+SimplexBase::SimplexBase(const FlatAffineConstraints &constraints)
+    : SimplexBase(constraints.getNumIds()) {
   for (unsigned i = 0, numIneqs = constraints.getNumInequalities();
        i < numIneqs; ++i)
     addInequality(constraints.getInequality(i));
@@ -37,32 +37,32 @@ Simplex::Simplex(const FlatAffineConstraints &constraints)
     addEquality(constraints.getEquality(i));
 }
 
-const Simplex::Unknown &Simplex::unknownFromIndex(int index) const {
+const Simplex::Unknown &SimplexBase::unknownFromIndex(int index) const {
   assert(index != nullIndex && "nullIndex passed to unknownFromIndex");
   return index >= 0 ? var[index] : con[~index];
 }
 
-const Simplex::Unknown &Simplex::unknownFromColumn(unsigned col) const {
+const Simplex::Unknown &SimplexBase::unknownFromColumn(unsigned col) const {
   assert(col < nCol && "Invalid column");
   return unknownFromIndex(colUnknown[col]);
 }
 
-const Simplex::Unknown &Simplex::unknownFromRow(unsigned row) const {
+const Simplex::Unknown &SimplexBase::unknownFromRow(unsigned row) const {
   assert(row < nRow && "Invalid row");
   return unknownFromIndex(rowUnknown[row]);
 }
 
-Simplex::Unknown &Simplex::unknownFromIndex(int index) {
+Simplex::Unknown &SimplexBase::unknownFromIndex(int index) {
   assert(index != nullIndex && "nullIndex passed to unknownFromIndex");
   return index >= 0 ? var[index] : con[~index];
 }
 
-Simplex::Unknown &Simplex::unknownFromColumn(unsigned col) {
+Simplex::Unknown &SimplexBase::unknownFromColumn(unsigned col) {
   assert(col < nCol && "Invalid column");
   return unknownFromIndex(colUnknown[col]);
 }
 
-Simplex::Unknown &Simplex::unknownFromRow(unsigned row) {
+Simplex::Unknown &SimplexBase::unknownFromRow(unsigned row) {
   assert(row < nRow && "Invalid row");
   return unknownFromIndex(rowUnknown[row]);
 }
@@ -70,7 +70,7 @@ Simplex::Unknown &Simplex::unknownFromRow(unsigned row) {
 /// Add a new row to the tableau corresponding to the given constant term and
 /// list of coefficients. The coefficients are specified as a vector of
 /// (variable index, coefficient) pairs.
-unsigned Simplex::addRow(ArrayRef<int64_t> coeffs) {
+unsigned SimplexBase::addRow(ArrayRef<int64_t> coeffs) {
   assert(coeffs.size() == 1 + var.size() &&
          "Incorrect number of coefficients!");
 
@@ -121,7 +121,7 @@ unsigned Simplex::addRow(ArrayRef<int64_t> coeffs) {
 
 /// Normalize the row by removing factors that are common between the
 /// denominator and all the numerator coefficients.
-void Simplex::normalizeRow(unsigned row) {
+void SimplexBase::normalizeRow(unsigned row) {
   int64_t gcd = 0;
   for (unsigned col = 0; col < nCol; ++col) {
     if (gcd == 1)
@@ -155,8 +155,8 @@ Direction flippedDirection(Direction direction) {
 ///
 /// If multiple columns are valid, we break ties by considering a lexicographic
 /// ordering where we prefer unknowns with lower index.
-Optional<Simplex::Pivot> Simplex::findPivot(int row,
-                                            Direction direction) const {
+Optional<SimplexBase::Pivot> SimplexBase::findPivot(int row,
+                                                    Direction direction) const {
   Optional<unsigned> col;
   for (unsigned j = 2; j < nCol; ++j) {
     int64_t elem = tableau(row, j);
@@ -183,7 +183,7 @@ Optional<Simplex::Pivot> Simplex::findPivot(int row,
 ///
 /// First we swap the index associated with the row and column. Then we update
 /// the unknowns to reflect their new position and orientation.
-void Simplex::swapRowWithCol(unsigned row, unsigned col) {
+void SimplexBase::swapRowWithCol(unsigned row, unsigned col) {
   std::swap(rowUnknown[row], colUnknown[col]);
   Unknown &uCol = unknownFromColumn(col);
   Unknown &uRow = unknownFromRow(row);
@@ -193,7 +193,7 @@ void Simplex::swapRowWithCol(unsigned row, unsigned col) {
   uRow.pos = row;
 }
 
-void Simplex::pivot(Pivot pair) { pivot(pair.row, pair.column); }
+void SimplexBase::pivot(Pivot pair) { pivot(pair.row, pair.column); }
 
 /// Pivot pivotRow and pivotCol.
 ///
@@ -220,7 +220,7 @@ void Simplex::pivot(Pivot pair) { pivot(pair.row, pair.column); }
 /// The pivot row transform is accomplished be swapping a with the pivot row's
 /// common denominator and negating the pivot row except for the pivot column
 /// element.
-void Simplex::pivot(unsigned pivotRow, unsigned pivotCol) {
+void SimplexBase::pivot(unsigned pivotRow, unsigned pivotCol) {
   assert(pivotCol >= 2 && "Refusing to pivot invalid column");
 
   swapRowWithCol(pivotRow, pivotCol);
@@ -261,7 +261,7 @@ void Simplex::pivot(unsigned pivotRow, unsigned pivotCol) {
 /// Perform pivots until the unknown has a non-negative sample value or until
 /// no more upward pivots can be performed. Return success if we were able to
 /// bring the row to a non-negative sample value, and failure otherwise.
-LogicalResult Simplex::restoreRow(Unknown &u) {
+LogicalResult SimplexBase::restoreRow(Unknown &u) {
   assert(u.orientation == Orientation::Row &&
          "unknown should be in row position");
 
@@ -299,9 +299,9 @@ LogicalResult Simplex::restoreRow(Unknown &u) {
 /// 0 and hence saturates the bound it imposes. We break ties between rows that
 /// impose the same bound by considering a lexicographic ordering where we
 /// prefer unknowns with lower index value.
-Optional<unsigned> Simplex::findPivotRow(Optional<unsigned> skipRow,
-                                         Direction direction,
-                                         unsigned col) const {
+Optional<unsigned> SimplexBase::findPivotRow(Optional<unsigned> skipRow,
+                                             Direction direction,
+                                             unsigned col) const {
   Optional<unsigned> retRow;
   int64_t retElem, retConst;
   for (unsigned row = nRedundant; row < nRow; ++row) {
@@ -334,9 +334,9 @@ Optional<unsigned> Simplex::findPivotRow(Optional<unsigned> skipRow,
   return retRow;
 }
 
-bool Simplex::isEmpty() const { return empty; }
+bool SimplexBase::isEmpty() const { return empty; }
 
-void Simplex::swapRows(unsigned i, unsigned j) {
+void SimplexBase::swapRows(unsigned i, unsigned j) {
   if (i == j)
     return;
   tableau.swapRows(i, j);
@@ -345,7 +345,7 @@ void Simplex::swapRows(unsigned i, unsigned j) {
   unknownFromRow(j).pos = j;
 }
 
-void Simplex::swapColumns(unsigned i, unsigned j) {
+void SimplexBase::swapColumns(unsigned i, unsigned j) {
   assert(i < nCol && j < nCol && "Invalid columns provided!");
   if (i == j)
     return;
@@ -356,7 +356,7 @@ void Simplex::swapColumns(unsigned i, unsigned j) {
 }
 
 /// Mark this tableau empty and push an entry to the undo stack.
-void Simplex::markEmpty() {
+void SimplexBase::markEmpty() {
   // If the set is already empty, then we shouldn't add another UnmarkEmpty log
   // entry, since in that case the Simplex will be erroneously marked as
   // non-empty when rolling back past this point.
@@ -373,7 +373,7 @@ void Simplex::markEmpty() {
 /// We add the inequality and mark it as restricted. We then try to make its
 /// sample value non-negative. If this is not possible, the tableau has become
 /// empty and we mark it as such.
-void Simplex::addInequality(ArrayRef<int64_t> coeffs) {
+void SimplexBase::addInequality(ArrayRef<int64_t> coeffs) {
   unsigned conIndex = addRow(coeffs);
   Unknown &u = con[conIndex];
   u.restricted = true;
@@ -388,7 +388,7 @@ void Simplex::addInequality(ArrayRef<int64_t> coeffs) {
 ///
 /// We simply add two opposing inequalities, which force the expression to
 /// be zero.
-void Simplex::addEquality(ArrayRef<int64_t> coeffs) {
+void SimplexBase::addEquality(ArrayRef<int64_t> coeffs) {
   addInequality(coeffs);
   SmallVector<int64_t, 8> negatedCoeffs;
   for (int64_t coeff : coeffs)
@@ -396,14 +396,14 @@ void Simplex::addEquality(ArrayRef<int64_t> coeffs) {
   addInequality(negatedCoeffs);
 }
 
-unsigned Simplex::getNumVariables() const { return var.size(); }
-unsigned Simplex::getNumConstraints() const { return con.size(); }
+unsigned SimplexBase::getNumVariables() const { return var.size(); }
+unsigned SimplexBase::getNumConstraints() const { return con.size(); }
 
 /// Return a snapshot of the current state. This is just the current size of the
 /// undo log.
-unsigned Simplex::getSnapshot() const { return undoLog.size(); }
+unsigned SimplexBase::getSnapshot() const { return undoLog.size(); }
 
-void Simplex::undo(UndoLogEntry entry) {
+void SimplexBase::undo(UndoLogEntry entry) {
   if (entry == UndoLogEntry::RemoveLastConstraint) {
     Unknown &constraint = con.back();
     if (constraint.orientation == Orientation::Column) {
@@ -480,14 +480,14 @@ void Simplex::undo(UndoLogEntry entry) {
 ///
 /// We undo all the log entries until the log size when the snapshot was taken
 /// is reached.
-void Simplex::rollback(unsigned snapshot) {
+void SimplexBase::rollback(unsigned snapshot) {
   while (undoLog.size() > snapshot) {
     undo(undoLog.back());
     undoLog.pop_back();
   }
 }
 
-void Simplex::appendVariable(unsigned count) {
+void SimplexBase::appendVariable(unsigned count) {
   if (count == 0)
     return;
   var.reserve(var.size() + count);
@@ -503,7 +503,8 @@ void Simplex::appendVariable(unsigned count) {
 }
 
 /// Add all the constraints from the given FlatAffineConstraints.
-void Simplex::intersectFlatAffineConstraints(const FlatAffineConstraints &fac) {
+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)
@@ -736,7 +737,7 @@ Simplex Simplex::makeProduct(const Simplex &a, const Simplex &b) {
   return result;
 }
 
-SmallVector<Fraction, 8> Simplex::getRationalSample() const {
+SmallVector<Fraction, 8> SimplexBase::getRationalSample() const {
   assert(!empty && "This should not be called when Simplex is empty.");
 
   SmallVector<Fraction, 8> sample;
@@ -756,7 +757,8 @@ SmallVector<Fraction, 8> Simplex::getRationalSample() const {
   return sample;
 }
 
-Optional<SmallVector<int64_t, 8>> Simplex::getSamplePointIfIntegral() const {
+Optional<SmallVector<int64_t, 8>>
+SimplexBase::getSamplePointIfIntegral() const {
   // If the tableau is empty, no sample point exists.
   if (empty)
     return {};
@@ -1246,7 +1248,7 @@ Simplex::computeIntegerBounds(ArrayRef<int64_t> coeffs) {
   return {minRoundedUp, maxRoundedDown};
 }
 
-void Simplex::print(raw_ostream &os) const {
+void SimplexBase::print(raw_ostream &os) const {
   os << "rows = " << nRow << ", columns = " << nCol << "\n";
   if (empty)
     os << "Simplex marked empty!\n";
@@ -1281,7 +1283,7 @@ void Simplex::print(raw_ostream &os) const {
   os << '\n';
 }
 
-void Simplex::dump() const { print(llvm::errs()); }
+void SimplexBase::dump() const { print(llvm::errs()); }
 
 bool Simplex::isRationalSubsetOf(const FlatAffineConstraints &fac) {
   if (isEmpty())


        


More information about the Mlir-commits mailing list