Skip to content

Commit a8aad6f

Browse files
committed
[MLIR][Presburger] Use Identifiers outside Presburger library
1 parent 513f62e commit a8aad6f

File tree

10 files changed

+253
-198
lines changed

10 files changed

+253
-198
lines changed

mlir/include/mlir/Analysis/FlatLinearValueConstraints.h

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ class FlatLinearConstraints : public presburger::IntegerPolyhedron {
205205
/// where each non-local variable can have an SSA Value attached to it.
206206
class FlatLinearValueConstraints : public FlatLinearConstraints {
207207
public:
208+
/// The SSA Values attached to each non-local variable are stored as
209+
/// identifiers in the constraint system's space.
210+
using Identifier = presburger::Identifier;
211+
208212
/// Constructs a constraint system reserving memory for the specified number
209213
/// of constraints and variables. `valArgs` are the optional SSA values
210214
/// associated with each dimension/symbol. These must either be empty or match
@@ -217,11 +221,11 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
217221
: FlatLinearConstraints(numReservedInequalities, numReservedEqualities,
218222
numReservedCols, numDims, numSymbols, numLocals) {
219223
assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
220-
values.reserve(numReservedCols);
221-
if (valArgs.empty())
222-
values.resize(getNumDimAndSymbolVars(), std::nullopt);
223-
else
224-
values.append(valArgs.begin(), valArgs.end());
224+
// Store Values in space's identifiers.
225+
space.resetIds();
226+
for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
227+
if (valArgs[i])
228+
setValue(i, *valArgs[i]);
225229
}
226230

227231
/// Constructs a constraint system reserving memory for the specified number
@@ -236,11 +240,11 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
236240
: FlatLinearConstraints(numReservedInequalities, numReservedEqualities,
237241
numReservedCols, numDims, numSymbols, numLocals) {
238242
assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
239-
values.reserve(numReservedCols);
240-
if (valArgs.empty())
241-
values.resize(getNumDimAndSymbolVars(), std::nullopt);
242-
else
243-
values.append(valArgs.begin(), valArgs.end());
243+
// Store Values in space's identifiers.
244+
space.resetIds();
245+
for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
246+
if (valArgs[i])
247+
setValue(i, valArgs[i]);
244248
}
245249

246250
/// Constructs a constraint system with the specified number of dimensions
@@ -272,11 +276,15 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
272276
FlatLinearValueConstraints(const IntegerPolyhedron &fac,
273277
ArrayRef<std::optional<Value>> valArgs = {})
274278
: FlatLinearConstraints(fac) {
275-
assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
279+
// Do not reset values assigned by FlatLinearConstraints' constructor.
276280
if (valArgs.empty())
277-
values.resize(getNumDimAndSymbolVars(), std::nullopt);
278-
else
279-
values.append(valArgs.begin(), valArgs.end());
281+
return;
282+
assert(valArgs.size() == getNumDimAndSymbolVars());
283+
// Store Values in space's identifiers.
284+
space.resetIds();
285+
for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
286+
if (valArgs[i])
287+
setValue(i, *valArgs[i]);
280288
}
281289

282290
/// Creates an affine constraint system from an IntegerSet.
@@ -290,9 +298,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
290298
cst->getKind() <= Kind::FlatAffineRelation;
291299
}
292300

293-
/// Replaces the contents of this FlatLinearValueConstraints with `other`.
294-
void clearAndCopyFrom(const IntegerRelation &other) override;
295-
296301
/// Adds a constant bound for the variable associated with the given Value.
297302
void addBound(presburger::BoundType type, Value val, int64_t value);
298303
using FlatLinearConstraints::addBound;
@@ -302,7 +307,9 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
302307
inline Value getValue(unsigned pos) const {
303308
assert(pos < getNumDimAndSymbolVars() && "Invalid position");
304309
assert(hasValue(pos) && "variable's Value not set");
305-
return *values[pos];
310+
VarKind kind = getVarKindAt(pos);
311+
unsigned relativePos = pos - getVarKindOffset(kind);
312+
return space.getId(kind, relativePos).getValue<Value>();
306313
}
307314

308315
/// Returns the Values associated with variables in range [start, end).
@@ -313,25 +320,44 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
313320
assert(start <= end && "invalid start position");
314321
values->clear();
315322
values->reserve(end - start);
316-
for (unsigned i = start; i < end; i++)
323+
for (unsigned i = start; i < end; ++i)
317324
values->push_back(getValue(i));
318325
}
319326

320-
inline ArrayRef<std::optional<Value>> getMaybeValues() const {
321-
return {values.data(), values.size()};
327+
inline SmallVector<std::optional<Value>> getMaybeValues() const {
328+
SmallVector<std::optional<Value>> maybeValues;
329+
maybeValues.reserve(getNumDimAndSymbolVars());
330+
for (unsigned i = 0, e = getNumDimAndSymbolVars(); i < e; ++i)
331+
if (hasValue(i)) {
332+
maybeValues.push_back(getValue(i));
333+
} else {
334+
maybeValues.push_back(std::nullopt);
335+
}
336+
return maybeValues;
322337
}
323338

324-
inline ArrayRef<std::optional<Value>>
339+
inline SmallVector<std::optional<Value>>
325340
getMaybeValues(presburger::VarKind kind) const {
326341
assert(kind != VarKind::Local &&
327342
"Local variables do not have any value attached to them.");
328-
return {values.data() + getVarKindOffset(kind), getNumVarKind(kind)};
343+
SmallVector<std::optional<Value>> maybeValues;
344+
maybeValues.reserve(getNumVarKind(kind));
345+
const unsigned offset = space.getVarKindOffset(kind);
346+
for (unsigned i = 0, e = getNumVarKind(kind); i < e; ++i) {
347+
if (hasValue(offset + i))
348+
maybeValues.push_back(getValue(offset + i));
349+
else
350+
maybeValues.push_back(std::nullopt);
351+
}
352+
return maybeValues;
329353
}
330354

331355
/// Returns true if the pos^th variable has an associated Value.
332356
inline bool hasValue(unsigned pos) const {
333357
assert(pos < getNumDimAndSymbolVars() && "Invalid position");
334-
return values[pos].has_value();
358+
VarKind kind = getVarKindAt(pos);
359+
unsigned relativePos = pos - getVarKindOffset(kind);
360+
return space.getId(kind, relativePos).hasValue();
335361
}
336362

337363
unsigned appendDimVar(ValueRange vals);
@@ -358,9 +384,15 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
358384
using IntegerPolyhedron::removeVarRange;
359385

360386
/// Sets the Value associated with the pos^th variable.
387+
/// Stores the Value in the space's identifiers.
361388
inline void setValue(unsigned pos, Value val) {
362389
assert(pos < getNumDimAndSymbolVars() && "invalid var position");
363-
values[pos] = val;
390+
VarKind kind = getVarKindAt(pos);
391+
unsigned relativePos = pos - getVarKindOffset(kind);
392+
if (!space.isUsingIds()) {
393+
space.resetIds();
394+
}
395+
space.getId(kind, relativePos) = presburger::Identifier(val);
364396
}
365397

366398
/// Sets the Values associated with the variables in the range [start, end).
@@ -387,9 +419,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
387419
void projectOut(Value val);
388420
using IntegerPolyhedron::projectOut;
389421

390-
/// Swap the posA^th variable with the posB^th variable.
391-
void swapVar(unsigned posA, unsigned posB) override;
392-
393422
/// Prints the number of constraints, dimensions, symbols and locals in the
394423
/// FlatAffineValueConstraints. Also, prints for each variable whether there
395424
/// is an SSA Value attached to it.
@@ -444,28 +473,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
444473
/// output = {0 <= d0 <= 6, 1 <= d1 <= 15}
445474
LogicalResult unionBoundingBox(const FlatLinearValueConstraints &other);
446475
using IntegerPolyhedron::unionBoundingBox;
447-
448-
protected:
449-
/// Eliminates the variable at the specified position using Fourier-Motzkin
450-
/// variable elimination, but uses Gaussian elimination if there is an
451-
/// equality involving that variable. If the result of the elimination is
452-
/// integer exact, `*isResultIntegerExact` is set to true. If `darkShadow` is
453-
/// set to true, a potential under approximation (subset) of the rational
454-
/// shadow / exact integer shadow is computed.
455-
// See implementation comments for more details.
456-
void fourierMotzkinEliminate(unsigned pos, bool darkShadow = false,
457-
bool *isResultIntegerExact = nullptr) override;
458-
459-
/// Returns false if the fields corresponding to various variable counts, or
460-
/// equality/inequality buffer sizes aren't consistent; true otherwise. This
461-
/// is meant to be used within an assert internally.
462-
bool hasConsistentState() const override;
463-
464-
/// Values corresponding to the (column) non-local variables of this
465-
/// constraint system appearing in the order the variables correspond to
466-
/// columns. Variables that aren't associated with any Value are set to
467-
/// std::nullopt.
468-
SmallVector<std::optional<Value>, 8> values;
469476
};
470477

471478
/// Flattens 'expr' into 'flattenedExpr', which contains the coefficients of the

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ class IntegerRelation {
127127
/// the variable.
128128
void setId(VarKind kind, unsigned i, Identifier id);
129129

130+
void resetIds() { space.resetIds(); }
131+
130132
/// Returns a copy of the space without locals.
131133
PresburgerSpace getSpaceWithoutLocals() const {
132134
return PresburgerSpace::getRelationSpace(space.getNumDomainVars(),
@@ -674,6 +676,11 @@ class IntegerRelation {
674676
/// this for uniformity with `applyDomain`.
675677
void applyRange(const IntegerRelation &rel);
676678

679+
/// Given a relation `other: (A -> B)`, this operation merges the symbol and
680+
/// local variables and then takes the composition of `other` on `this: (B ->
681+
/// C)`. The resulting relation represents tuples of the form: `A -> C`.
682+
void mergeAndCompose(const IntegerRelation &other);
683+
677684
/// Compute an equivalent representation of the same set, such that all local
678685
/// vars in all disjuncts have division representations. This representation
679686
/// may involve local vars that correspond to divisions, and may also be a

mlir/include/mlir/Analysis/Presburger/PresburgerSpace.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,12 @@ class PresburgerSpace {
250250
/// locals).
251251
bool isEqual(const PresburgerSpace &other) const;
252252

253-
/// Get the identifier of the specified variable.
253+
/// Get a mutable reference to the identifier of the specified variable.
254254
Identifier &getId(VarKind kind, unsigned pos) {
255255
assert(kind != VarKind::Local && "Local variables have no identifiers");
256256
return identifiers[getVarKindOffset(kind) + pos];
257257
}
258+
258259
Identifier getId(VarKind kind, unsigned pos) const {
259260
assert(kind != VarKind::Local && "Local variables have no identifiers");
260261
return identifiers[getVarKindOffset(kind) + pos];
@@ -265,6 +266,8 @@ class PresburgerSpace {
265266
return {identifiers.data() + getVarKindOffset(kind), getNumVarKind(kind)};
266267
}
267268

269+
ArrayRef<Identifier> getIds() const { return identifiers; }
270+
268271
/// Returns if identifiers are being used.
269272
bool isUsingIds() const { return usingIds; }
270273

mlir/include/mlir/Dialect/Affine/Analysis/AffineAnalysis.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef MLIR_DIALECT_AFFINE_ANALYSIS_AFFINEANALYSIS_H
1616
#define MLIR_DIALECT_AFFINE_ANALYSIS_AFFINEANALYSIS_H
1717

18+
#include "mlir/Analysis/Presburger/IntegerRelation.h"
1819
#include "mlir/Dialect/Arith/IR/Arith.h"
1920
#include "mlir/IR/Value.h"
2021
#include "llvm/ADT/SmallVector.h"
@@ -115,7 +116,7 @@ struct MemRefAccess {
115116
///
116117
/// Returns failure for yet unimplemented/unsupported cases (see docs of
117118
/// mlir::getIndexSet and mlir::getRelationFromMap for these cases).
118-
LogicalResult getAccessRelation(FlatAffineRelation &accessRel) const;
119+
LogicalResult getAccessRelation(presburger::IntegerRelation &accessRel) const;
119120

120121
/// Populates 'accessMap' with composition of AffineApplyOps reachable from
121122
/// 'indices'.

mlir/include/mlir/Dialect/Affine/Analysis/AffineStructures.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ class FlatAffineValueConstraints : public FlatLinearValueConstraints {
154154
/// represented as a FlatAffineValueConstraints with separation of dimension
155155
/// variables into domain and range. The variables are stored as:
156156
/// [domainVars, rangeVars, symbolVars, localVars, constant].
157+
///
158+
/// Deprecated: use IntegerRelation and store SSA Values in the PresburgerSpace
159+
/// of the relation using PresburgerSpace::identifiers. Note that
160+
/// FlatAffineRelation::numDomainDims and FlatAffineRelation::numRangeDims are
161+
/// independent of numDomain and numRange of the relation's space. In
162+
/// particular, operations such as FlatAffineRelation::compose do not ensure
163+
/// consistency between numDomainDims/numRangeDims and numDomain/numRange which
164+
/// may lead to unexpected behaviour.
157165
class FlatAffineRelation : public FlatAffineValueConstraints {
158166
public:
159167
FlatAffineRelation(unsigned numReservedInequalities,
@@ -251,9 +259,10 @@ class FlatAffineRelation : public FlatAffineValueConstraints {
251259
/// For AffineValueMap, the domain and symbols have Value set corresponding to
252260
/// the Value in `map`. Returns failure if the AffineMap could not be flattened
253261
/// (i.e., semi-affine is not yet handled).
254-
LogicalResult getRelationFromMap(AffineMap &map, FlatAffineRelation &rel);
262+
LogicalResult getRelationFromMap(AffineMap &map,
263+
presburger::IntegerRelation &rel);
255264
LogicalResult getRelationFromMap(const AffineValueMap &map,
256-
FlatAffineRelation &rel);
265+
presburger::IntegerRelation &rel);
257266

258267
} // namespace affine
259268
} // namespace mlir

0 commit comments

Comments
 (0)