[MLIR][Presburger] Support isSubsetOf in PresburgerSet and IntegerPolyhedron

Also support isEqual in IntegerPolyhedron.

Reviewed By: Groverkss

Differential Revision: https://reviews.llvm.org/D118778
This commit is contained in:
Arjun P 2022-02-02 18:37:13 +05:30
parent a007a6d844
commit ec10ff37e2
4 changed files with 31 additions and 9 deletions

View File

@ -115,6 +115,16 @@ public:
/// intersection with no simplification of any sort attempted. /// intersection with no simplification of any sort attempted.
void append(const IntegerPolyhedron &other); void append(const IntegerPolyhedron &other);
/// Return whether `this` and `other` are equal. This is integer-exact
/// and somewhat expensive, since it uses the integer emptiness check
/// (see IntegerPolyhedron::findIntegerSample()).
bool isEqual(const IntegerPolyhedron &other) const;
/// Return whether this is a subset of the given IntegerPolyhedron. This is
/// integer-exact and somewhat expensive, since it uses the integer emptiness
/// check (see IntegerPolyhedron::findIntegerSample()).
bool isSubsetOf(const IntegerPolyhedron &other) const;
/// Returns the value at the specified equality row and column. /// 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) const { return equalities(i, j); }
inline int64_t &atEq(unsigned i, unsigned j) { return equalities(i, j); } inline int64_t &atEq(unsigned i, unsigned j) { return equalities(i, j); }

View File

@ -77,6 +77,9 @@ public:
/// divisions. /// divisions.
PresburgerSet subtract(const PresburgerSet &set) const; PresburgerSet subtract(const PresburgerSet &set) const;
/// Return true if this set is a subset of the given set, and false otherwise.
bool isSubsetOf(const PresburgerSet &set) const;
/// Return true if this set is equal to the given set, and false otherwise. /// Return true if this set is equal to the given set, and false otherwise.
/// All local variables in both sets must correspond to floor divisions. /// All local variables in both sets must correspond to floor divisions.
bool isEqual(const PresburgerSet &set) const; bool isEqual(const PresburgerSet &set) const;

View File

@ -12,6 +12,7 @@
#include "mlir/Analysis/Presburger/IntegerPolyhedron.h" #include "mlir/Analysis/Presburger/IntegerPolyhedron.h"
#include "mlir/Analysis/Presburger/LinearTransform.h" #include "mlir/Analysis/Presburger/LinearTransform.h"
#include "mlir/Analysis/Presburger/PresburgerSet.h"
#include "mlir/Analysis/Presburger/Simplex.h" #include "mlir/Analysis/Presburger/Simplex.h"
#include "mlir/Analysis/Presburger/Utils.h" #include "mlir/Analysis/Presburger/Utils.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
@ -63,6 +64,14 @@ void IntegerPolyhedron::append(const IntegerPolyhedron &other) {
} }
} }
bool IntegerPolyhedron::isEqual(const IntegerPolyhedron &other) const {
return PresburgerSet(*this).isEqual(PresburgerSet(other));
}
bool IntegerPolyhedron::isSubsetOf(const IntegerPolyhedron &other) const {
return PresburgerSet(*this).isSubsetOf(PresburgerSet(other));
}
Optional<SmallVector<Fraction, 8>> Optional<SmallVector<Fraction, 8>>
IntegerPolyhedron::getRationalLexMin() const { IntegerPolyhedron::getRationalLexMin() const {
assert(numSymbols == 0 && "Symbols are not supported!"); assert(numSymbols == 0 && "Symbols are not supported!");

View File

@ -352,17 +352,17 @@ PresburgerSet PresburgerSet::subtract(const PresburgerSet &set) const {
return result; return result;
} }
/// Two sets S and T are equal iff S contains T and T contains S. /// T is a subset of S iff T \ S is empty, since if T \ S contains a
/// By "S contains T", we mean that S is a superset of or equal to T. /// point then this is a point that is contained in T but not S, and
/// /// if T contains a point that is not in S, this also lies in T \ S.
/// S contains T iff T \ S is empty, since if T \ S contains a bool PresburgerSet::isSubsetOf(const PresburgerSet &set) const {
/// point then this is a point that is contained in T but not S. return this->subtract(set).isIntegerEmpty();
/// }
/// Therefore, S is equal to T iff S \ T and T \ S are both empty.
/// Two sets are equal iff they are subsets of each other.
bool PresburgerSet::isEqual(const PresburgerSet &set) const { bool PresburgerSet::isEqual(const PresburgerSet &set) const {
assertDimensionsCompatible(set, *this); assertDimensionsCompatible(set, *this);
return this->subtract(set).isIntegerEmpty() && return this->isSubsetOf(set) && set.isSubsetOf(*this);
set.subtract(*this).isIntegerEmpty();
} }
/// Return true if all the sets in the union are known to be integer empty, /// Return true if all the sets in the union are known to be integer empty,