Skip to content

Commit da92f92

Browse files
committed
[MLIR][Presburger] IntegerPolyhedron: add support for symbolic integer lexmin
Add support for computing the symbolic integer lexmin of a polyhedron. This finds, for every assignment to the symbols, the lexicographically minimum value attained by the dimensions. For example, the symbolic lexmin of the set `(x, y)[a, b, c] : (a <= x, b <= x, x <= c)` can be written as ``` x = a if b <= a, a <= c x = b if a < b, b <= c ``` This also finds the set of assignments to the symbols that make the lexmin unbounded. Reviewed By: Groverkss Differential Revision: https://reviews.llvm.org/D122985
1 parent 3b98335 commit da92f92

File tree

9 files changed

+970
-128
lines changed

9 files changed

+970
-128
lines changed

mlir/include/mlir/Analysis/Presburger/IntegerRelation.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ class IntegerRelation : public PresburgerSpace {
536536
Matrix inequalities;
537537
};
538538

539+
struct SymbolicLexMin;
539540
/// An IntegerPolyhedron is a PresburgerSpace subject to affine
540541
/// constraints. Affine constraints can be inequalities or equalities in the
541542
/// form:
@@ -593,6 +594,28 @@ class IntegerPolyhedron : public IntegerRelation {
593594
/// column position (i.e., not relative to the kind of identifier) of the
594595
/// first added identifier.
595596
unsigned insertId(IdKind kind, unsigned pos, unsigned num = 1) override;
597+
598+
/// Compute the symbolic integer lexmin of the polyhedron.
599+
/// This finds, for every assignment to the symbols, the lexicographically
600+
/// minimum value attained by the dimensions. For example, the symbolic lexmin
601+
/// of the set
602+
///
603+
/// (x, y)[a, b, c] : (a <= x, b <= x, x <= c)
604+
///
605+
/// can be written as
606+
///
607+
/// x = a if b <= a, a <= c
608+
/// x = b if a < b, b <= c
609+
///
610+
/// This function is stored in the `lexmin` function in the result.
611+
/// Some assignments to the symbols might make the set empty.
612+
/// Such points are not part of the function's domain.
613+
/// In the above example, this happens when max(a, b) > c.
614+
///
615+
/// For some values of the symbols, the lexmin may be unbounded.
616+
/// `SymbolicLexMin` stores these parts of the symbolic domain in a separate
617+
/// `PresburgerSet`, `unboundedDomain`.
618+
SymbolicLexMin findSymbolicIntegerLexMin() const;
596619
};
597620

598621
} // namespace presburger

mlir/include/mlir/Analysis/Presburger/Matrix.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ class Matrix {
151151

152152
/// Add an extra row at the bottom of the matrix and return its position.
153153
unsigned appendExtraRow();
154+
/// Same as above, but copy the given elements into the row. The length of
155+
/// `elems` must be equal to the number of columns.
156+
unsigned appendExtraRow(ArrayRef<int64_t> elems);
154157

155158
/// Print the matrix.
156159
void print(raw_ostream &os) const;

mlir/include/mlir/Analysis/Presburger/PWMAFunction.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ class MultiAffineFunction : protected IntegerPolyhedron {
106106
/// outside the domain, an empty optional is returned.
107107
Optional<SmallVector<int64_t, 8>> valueAt(ArrayRef<int64_t> point) const;
108108

109+
/// Truncate the output dimensions to the first `count` dimensions.
110+
///
111+
/// TODO: refactor so that this can be accomplished through removeIdRange.
112+
void truncateOutput(unsigned count);
113+
109114
void print(raw_ostream &os) const;
110115
void dump() const;
111116

@@ -165,6 +170,11 @@ class PWMAFunction : public PresburgerSpace {
165170
/// value at every point in the domain.
166171
bool isEqual(const PWMAFunction &other) const;
167172

173+
/// Truncate the output dimensions to the first `count` dimensions.
174+
///
175+
/// TODO: refactor so that this can be accomplished through removeIdRange.
176+
void truncateOutput(unsigned count);
177+
168178
void print(raw_ostream &os) const;
169179
void dump() const;
170180

mlir/include/mlir/Analysis/Presburger/Simplex.h

Lines changed: 210 additions & 84 deletions
Large diffs are not rendered by default.

mlir/lib/Analysis/Presburger/IntegerRelation.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "mlir/Analysis/Presburger/IntegerRelation.h"
1616
#include "mlir/Analysis/Presburger/LinearTransform.h"
17+
#include "mlir/Analysis/Presburger/PWMAFunction.h"
1718
#include "mlir/Analysis/Presburger/PresburgerRelation.h"
1819
#include "mlir/Analysis/Presburger/Simplex.h"
1920
#include "mlir/Analysis/Presburger/Utils.h"
@@ -145,6 +146,21 @@ void IntegerRelation::truncate(const CountsSnapshot &counts) {
145146
removeEqualityRange(counts.getNumEqs(), getNumEqualities());
146147
}
147148

149+
SymbolicLexMin IntegerPolyhedron::findSymbolicIntegerLexMin() const {
150+
// Compute the symbolic lexmin of the dims and locals, with the symbols being
151+
// the actual symbols of this set.
152+
SymbolicLexMin result =
153+
SymbolicLexSimplex(
154+
*this, PresburgerSpace::getSetSpace(/*numDims=*/getNumSymbolIds()))
155+
.computeSymbolicIntegerLexMin();
156+
157+
// We want to return only the lexmin over the dims, so strip the locals from
158+
// the computed lexmin.
159+
result.lexmin.truncateOutput(result.lexmin.getNumOutputs() -
160+
getNumLocalIds());
161+
return result;
162+
}
163+
148164
unsigned IntegerRelation::insertId(IdKind kind, unsigned pos, unsigned num) {
149165
assert(pos <= getNumIdKind(kind));
150166

mlir/lib/Analysis/Presburger/Matrix.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ unsigned Matrix::appendExtraRow() {
6666
return nRows - 1;
6767
}
6868

69+
unsigned Matrix::appendExtraRow(ArrayRef<int64_t> elems) {
70+
assert(elems.size() == nColumns && "elems must match row length!");
71+
unsigned row = appendExtraRow();
72+
for (unsigned col = 0; col < nColumns; ++col)
73+
at(row, col) = elems[col];
74+
return row;
75+
}
76+
6977
void Matrix::resizeHorizontally(unsigned newNColumns) {
7078
if (newNColumns < nColumns)
7179
removeColumns(newNColumns, nColumns - newNColumns);

mlir/lib/Analysis/Presburger/PWMAFunction.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,18 @@ void MultiAffineFunction::eliminateRedundantLocalId(unsigned posA,
114114
IntegerPolyhedron::eliminateRedundantLocalId(posA, posB);
115115
}
116116

117+
void MultiAffineFunction::truncateOutput(unsigned count) {
118+
assert(count <= output.getNumRows());
119+
output.resizeVertically(count);
120+
}
121+
122+
void PWMAFunction::truncateOutput(unsigned count) {
123+
assert(count <= numOutputs);
124+
for (MultiAffineFunction &piece : pieces)
125+
piece.truncateOutput(count);
126+
numOutputs = count;
127+
}
128+
117129
bool MultiAffineFunction::isEqualWhereDomainsOverlap(
118130
MultiAffineFunction other) const {
119131
if (!isSpaceCompatible(other))

0 commit comments

Comments
 (0)