Skip to content

Commit 1bd0c43

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

File tree

10 files changed

+250
-198
lines changed

10 files changed

+250
-198
lines changed

mlir/include/mlir/Analysis/FlatLinearValueConstraints.h

Lines changed: 48 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,9 @@ 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+
for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
225+
if (valArgs[i])
226+
setValue(i, *valArgs[i]);
225227
}
226228

227229
/// Constructs a constraint system reserving memory for the specified number
@@ -236,11 +238,9 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
236238
: FlatLinearConstraints(numReservedInequalities, numReservedEqualities,
237239
numReservedCols, numDims, numSymbols, numLocals) {
238240
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());
241+
for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
242+
if (valArgs[i])
243+
setValue(i, valArgs[i]);
244244
}
245245

246246
/// Constructs a constraint system with the specified number of dimensions
@@ -272,11 +272,13 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
272272
FlatLinearValueConstraints(const IntegerPolyhedron &fac,
273273
ArrayRef<std::optional<Value>> valArgs = {})
274274
: FlatLinearConstraints(fac) {
275-
assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
275+
// Do not reset values assigned by FlatLinearConstraints' constructor.
276276
if (valArgs.empty())
277-
values.resize(getNumDimAndSymbolVars(), std::nullopt);
278-
else
279-
values.append(valArgs.begin(), valArgs.end());
277+
return;
278+
assert(valArgs.size() == getNumDimAndSymbolVars());
279+
for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
280+
if (valArgs[i])
281+
setValue(i, *valArgs[i]);
280282
}
281283

282284
/// Creates an affine constraint system from an IntegerSet.
@@ -290,9 +292,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
290292
cst->getKind() <= Kind::FlatAffineRelation;
291293
}
292294

293-
/// Replaces the contents of this FlatLinearValueConstraints with `other`.
294-
void clearAndCopyFrom(const IntegerRelation &other) override;
295-
296295
/// Adds a constant bound for the variable associated with the given Value.
297296
void addBound(presburger::BoundType type, Value val, int64_t value);
298297
using FlatLinearConstraints::addBound;
@@ -302,7 +301,9 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
302301
inline Value getValue(unsigned pos) const {
303302
assert(pos < getNumDimAndSymbolVars() && "Invalid position");
304303
assert(hasValue(pos) && "variable's Value not set");
305-
return *values[pos];
304+
VarKind kind = getVarKindAt(pos);
305+
unsigned relativePos = pos - getVarKindOffset(kind);
306+
return space.getId(kind, relativePos).getValue<Value>();
306307
}
307308

308309
/// Returns the Values associated with variables in range [start, end).
@@ -313,25 +314,44 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
313314
assert(start <= end && "invalid start position");
314315
values->clear();
315316
values->reserve(end - start);
316-
for (unsigned i = start; i < end; i++)
317+
for (unsigned i = start; i < end; ++i)
317318
values->push_back(getValue(i));
318319
}
319320

320-
inline ArrayRef<std::optional<Value>> getMaybeValues() const {
321-
return {values.data(), values.size()};
321+
inline SmallVector<std::optional<Value>> getMaybeValues() const {
322+
SmallVector<std::optional<Value>> maybeValues;
323+
maybeValues.reserve(getNumDimAndSymbolVars());
324+
for (unsigned i = 0, e = getNumDimAndSymbolVars(); i < e; ++i)
325+
if (hasValue(i)) {
326+
maybeValues.push_back(getValue(i));
327+
} else {
328+
maybeValues.push_back(std::nullopt);
329+
}
330+
return maybeValues;
322331
}
323332

324-
inline ArrayRef<std::optional<Value>>
333+
inline SmallVector<std::optional<Value>>
325334
getMaybeValues(presburger::VarKind kind) const {
326335
assert(kind != VarKind::Local &&
327336
"Local variables do not have any value attached to them.");
328-
return {values.data() + getVarKindOffset(kind), getNumVarKind(kind)};
337+
SmallVector<std::optional<Value>> maybeValues;
338+
maybeValues.reserve(getNumVarKind(kind));
339+
const unsigned offset = space.getVarKindOffset(kind);
340+
for (unsigned i = 0, e = getNumVarKind(kind); i < e; ++i) {
341+
if (hasValue(offset + i))
342+
maybeValues.push_back(getValue(offset + i));
343+
else
344+
maybeValues.push_back(std::nullopt);
345+
}
346+
return maybeValues;
329347
}
330348

331349
/// Returns true if the pos^th variable has an associated Value.
332350
inline bool hasValue(unsigned pos) const {
333351
assert(pos < getNumDimAndSymbolVars() && "Invalid position");
334-
return values[pos].has_value();
352+
VarKind kind = getVarKindAt(pos);
353+
unsigned relativePos = pos - getVarKindOffset(kind);
354+
return space.isUsingIds() && space.getId(kind, relativePos).hasValue();
335355
}
336356

337357
unsigned appendDimVar(ValueRange vals);
@@ -358,9 +378,12 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
358378
using IntegerPolyhedron::removeVarRange;
359379

360380
/// Sets the Value associated with the pos^th variable.
381+
/// Stores the Value in the space's identifiers.
361382
inline void setValue(unsigned pos, Value val) {
362383
assert(pos < getNumDimAndSymbolVars() && "invalid var position");
363-
values[pos] = val;
384+
VarKind kind = getVarKindAt(pos);
385+
unsigned relativePos = pos - getVarKindOffset(kind);
386+
space.getId(kind, relativePos) = presburger::Identifier(val);
364387
}
365388

366389
/// Sets the Values associated with the variables in the range [start, end).
@@ -387,9 +410,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
387410
void projectOut(Value val);
388411
using IntegerPolyhedron::projectOut;
389412

390-
/// Swap the posA^th variable with the posB^th variable.
391-
void swapVar(unsigned posA, unsigned posB) override;
392-
393413
/// Prints the number of constraints, dimensions, symbols and locals in the
394414
/// FlatAffineValueConstraints. Also, prints for each variable whether there
395415
/// is an SSA Value attached to it.
@@ -444,28 +464,6 @@ class FlatLinearValueConstraints : public FlatLinearConstraints {
444464
/// output = {0 <= d0 <= 6, 1 <= d1 <= 15}
445465
LogicalResult unionBoundingBox(const FlatLinearValueConstraints &other);
446466
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;
469467
};
470468

471469
/// 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: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,21 +250,29 @@ 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.
254+
/// Enables `usingIds` if it was `false` before.
254255
Identifier &getId(VarKind kind, unsigned pos) {
255256
assert(kind != VarKind::Local && "Local variables have no identifiers");
257+
if (!usingIds)
258+
resetIds();
256259
return identifiers[getVarKindOffset(kind) + pos];
257260
}
261+
258262
Identifier getId(VarKind kind, unsigned pos) const {
259263
assert(kind != VarKind::Local && "Local variables have no identifiers");
264+
assert(usingIds && "Identifiers not enabled for space");
260265
return identifiers[getVarKindOffset(kind) + pos];
261266
}
262267

263268
ArrayRef<Identifier> getIds(VarKind kind) const {
264269
assert(kind != VarKind::Local && "Local variables have no identifiers");
270+
assert(usingIds && "Identifiers not enabled for space");
265271
return {identifiers.data() + getVarKindOffset(kind), getNumVarKind(kind)};
266272
}
267273

274+
ArrayRef<Identifier> getIds() const { return identifiers; }
275+
268276
/// Returns if identifiers are being used.
269277
bool isUsingIds() const { return usingIds; }
270278

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)