MLIR 24.0.0git
FlatLinearValueConstraints.h
Go to the documentation of this file.
1//===- FlatLinearValueConstraints.h - Linear Constraints --------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef MLIR_ANALYSIS_FLATLINEARVALUECONSTRAINTS_H
10#define MLIR_ANALYSIS_FLATLINEARVALUECONSTRAINTS_H
11
13#include "mlir/IR/AffineExpr.h"
14#include "mlir/IR/Value.h"
15#include "mlir/IR/ValueRange.h"
16#include <optional>
17
18namespace mlir {
19
20class AffineMap;
21class IntegerSet;
22class MLIRContext;
23class MemRefType;
24struct MutableAffineMap;
25
26namespace presburger {
28} // namespace presburger
29
30/// FlatLinearConstraints is an extension of IntegerPolyhedron. It provides an
31/// AffineExpr-based API.
33public:
34 /// Constructs a constraint system reserving memory for the specified number
35 /// of constraints and variables. `valArgs` are the optional SSA values
36 /// associated with each dimension/symbol. These must either be empty or match
37 /// the number of dimensions and symbols.
38 FlatLinearConstraints(unsigned numReservedInequalities,
39 unsigned numReservedEqualities,
40 unsigned numReservedCols, unsigned numDims,
41 unsigned numSymbols, unsigned numLocals)
42 : IntegerPolyhedron(numReservedInequalities, numReservedEqualities,
43 numReservedCols,
44 presburger::PresburgerSpace::getSetSpace(
45 numDims, numSymbols, numLocals)) {
46 assert(numReservedCols >= getNumVars() + 1);
47 }
48
49 /// Constructs a constraint system with the specified number of dimensions
50 /// and symbols. `valArgs` are the optional SSA values associated with each
51 /// dimension/symbol. These must either be empty or match the number of
52 /// dimensions and symbols.
53 FlatLinearConstraints(unsigned numDims = 0, unsigned numSymbols = 0,
54 unsigned numLocals = 0)
55 : FlatLinearConstraints(/*numReservedInequalities=*/0,
56 /*numReservedEqualities=*/0,
57 /*numReservedCols=*/numDims + numSymbols +
58 numLocals + 1,
59 numDims, numSymbols, numLocals) {}
60
63
64 /// Return the kind of this object.
65 Kind getKind() const override { return Kind::FlatLinearConstraints; }
66
67 /// Flag to control if conservative semi-affine bounds should be added in
68 /// `addBound()`.
70
71 /// Adds a bound for the variable at the specified position with constraints
72 /// being drawn from the specified bound map. In case of an EQ bound, the
73 /// bound map is expected to have exactly one result. In case of a LB/UB, the
74 /// bound map may have more than one result, for each of which an inequality
75 /// is added.
76 ///
77 /// The bound can be added as open or closed by specifying isClosedBound. In
78 /// case of a LB/UB, isClosedBound = false means the bound is added internally
79 /// as a closed bound by +1/-1 respectively. In case of an EQ bound, it can
80 /// only be added as a closed bound.
81 ///
82 /// Conservative bounds for semi-affine expressions will be added if
83 /// `AddConservativeSemiAffineBounds` is set to `Yes`. This currently only
84 /// covers semi-affine `mod` expressions, so `addBound()` will still fail if
85 /// it encounters a semi-affine `floordiv`, `ceildiv`, or `mul`. Note: If
86 /// enabled it is possible for the resulting constraint set to become empty if
87 /// a precondition of a conservative bound is found not to hold.
88 ///
89 /// Note: The dimensions/symbols of this FlatLinearConstraints must match the
90 /// dimensions/symbols of the affine map.
91 LogicalResult addBound(
92 presburger::BoundType type, unsigned pos, AffineMap boundMap,
93 bool isClosedBound,
95
96 /// Adds a bound for the variable at the specified position with constraints
97 /// being drawn from the specified bound map. In case of an EQ bound, the
98 /// bound map is expected to have exactly one result. In case of a LB/UB, the
99 /// bound map may have more than one result, for each of which an inequality
100 /// is added.
101 ///
102 /// Conservative bounds for semi-affine expressions will be added if
103 /// `AddConservativeSemiAffineBounds` is set to `Yes`. This currently only
104 /// covers semi-affine `mod` expressions, so `addBound()` will still fail if
105 /// it encounters a semi-affine `floordiv`, `ceildiv`, or `mul`. Note: If
106 /// enabled it is possible for the resulting constraint set to become empty if
107 /// a precondition of a conservative bound is found not to hold.
108 ///
109 /// Note: The dimensions/symbols of this FlatLinearConstraints must match the
110 /// dimensions/symbols of the affine map. By default the lower bound is closed
111 /// and the upper bound is open.
112 LogicalResult addBound(
113 presburger::BoundType type, unsigned pos, AffineMap boundMap,
115
116 /// The `addBound` overload above hides the inherited overloads by default, so
117 /// we explicitly introduce them here.
118 using IntegerPolyhedron::addBound;
119
120 /// Returns a non-negative constant bound on the extent (upper bound - lower
121 /// bound) of the specified variable if it is found to be a constant; returns
122 /// std::nullopt if it's not a constant. This method treats symbolic
123 /// variables specially, i.e., it looks for constant differences between
124 /// affine expressions involving only the symbolic variables. 'lb', if
125 /// provided, is set to the lower bound map associated with the constant
126 /// difference, and similarly, `ub` to the upper bound. Note that 'lb', 'ub'
127 /// are purely symbolic and will correspond to the symbolic variables of the
128 /// constaint set.
129 // Egs: 0 <= i <= 15, return 16.
130 // s0 + 2 <= i <= s0 + 17, returns 16. (s0 has to be a symbol)
131 // s0 + s1 + 16 <= d0 <= s0 + s1 + 31, returns 16.
132 // s0 - 7 <= 8*j <= s0 returns 1 with lb = s0, lbDivisor = 8 (since lb =
133 // ceil(s0 - 7 / 8) = floor(s0 / 8)).
134 /// The difference between this method and
135 /// IntegerRelation::getConstantBoundOnDimSize is that unlike the latter, this
136 /// makes use of affine expressions and maps in its inference and provides
137 /// output with affine maps; it thus handles local variables by detecting them
138 /// as affine functions of the symbols when possible.
139 std::optional<int64_t>
140 getConstantBoundOnDimSize(MLIRContext *context, unsigned pos,
141 AffineMap *lb = nullptr, AffineMap *ub = nullptr,
142 unsigned *minLbPos = nullptr,
143 unsigned *minUbPos = nullptr) const;
144
145 /// Returns the constraint system as an integer set. Returns a null integer
146 /// set if the system has no constraints, or if an integer set couldn't be
147 /// constructed as a result of a local variable's explicit representation not
148 /// being known and such a local variable appearing in any of the constraints.
149 IntegerSet getAsIntegerSet(MLIRContext *context) const;
150
151 /// Computes the lower and upper bounds of the first `num` dimensional
152 /// variables (starting at `offset`) as an affine map of the remaining
153 /// variables (dimensional and symbolic). This method is able to detect
154 /// variables as floordiv's and mod's of affine expressions of other
155 /// variables with respect to (positive) constants. Sets bound map to a
156 /// null AffineMap if such a bound can't be found (or yet unimplemented).
157 ///
158 /// By default the returned lower bounds are closed and upper bounds are open.
159 /// If `closedUb` is true, the upper bound is closed.
160 ///
161 /// An upper bound built from more than one inequality is the min of them.
162 /// Only a caller that can consume such a bound should ask for it, via
163 /// `allowMultiResultUb`; the rest are given the constant upper bound
164 /// instead, which is weaker but always a single result.
165 void getSliceBounds(unsigned offset, unsigned num, MLIRContext *context,
167 SmallVectorImpl<AffineMap> *ubMaps, bool closedUB = false,
168 bool allowMultiResultUB = false);
169
170 /// Composes an affine map whose dimensions and symbols match one to one with
171 /// the dimensions and symbols of this FlatLinearConstraints. The results of
172 /// the map `other` are added as the leading dimensions of this constraint
173 /// system. Returns failure if `other` is a semi-affine map.
174 LogicalResult composeMatchingMap(AffineMap other);
175
176 /// Gets the lower and upper bound of the `offset` + `pos`th variable
177 /// treating [0, offset) U [offset + num, symStartPos) as dimensions and
178 /// [symStartPos, getNumDimAndSymbolVars) as symbols, and `pos` lies in
179 /// [0, num). The multi-dimensional maps in the returned pair represent the
180 /// max and min of potentially multiple affine expressions. `localExprs` holds
181 /// pre-computed AffineExpr's for all local variables in the system.
182 ///
183 /// By default the returned lower bounds are closed and upper bounds are open.
184 /// If `closedUb` is true, the upper bound is closed.
185 std::pair<AffineMap, AffineMap>
186 getLowerAndUpperBound(unsigned pos, unsigned offset, unsigned num,
187 unsigned symStartPos, ArrayRef<AffineExpr> localExprs,
188 MLIRContext *context, bool closedUB = false) const;
189
190 /// Insert variables of the specified kind at position `pos`. Positions are
191 /// relative to the kind of variable. The coefficient columns corresponding
192 /// to the added variables are initialized to zero. `vals` are the Values
193 /// corresponding to the variables. Values should not be used with
194 /// VarKind::Local since values can only be attached to non-local variables.
195 /// Return the absolute column position (i.e., not relative to the kind of
196 /// variable) of the first added variable.
197 ///
198 /// Note: Empty Values are allowed in `vals`.
199 unsigned insertDimVar(unsigned pos, unsigned num = 1) {
200 return insertVar(VarKind::SetDim, pos, num);
201 }
202 unsigned insertSymbolVar(unsigned pos, unsigned num = 1) {
203 return insertVar(VarKind::Symbol, pos, num);
204 }
205 unsigned insertLocalVar(unsigned pos, unsigned num = 1) {
206 return insertVar(VarKind::Local, pos, num);
207 }
208
209 /// Append variables of the specified kind after the last variable of that
210 /// kind. The coefficient columns corresponding to the added variables are
211 /// initialized to zero. `vals` are the Values corresponding to the
212 /// variables. Return the absolute column position (i.e., not relative to the
213 /// kind of variable) of the first appended variable.
214 ///
215 /// Note: Empty Values are allowed in `vals`.
216 unsigned appendDimVar(unsigned num = 1) {
217 return appendVar(VarKind::SetDim, num);
218 }
219 unsigned appendSymbolVar(unsigned num = 1) {
220 return appendVar(VarKind::Symbol, num);
221 }
222 unsigned appendLocalVar(unsigned num = 1) {
223 return appendVar(VarKind::Local, num);
224 }
225
226 /// A more human-readable version of dump().
227 void dumpPretty() const;
228 /// An easier to read dump of a `row` of the same width as the number of
229 /// columns. `fixedColWidth` ensure that even with a zero coefficient, we
230 /// print spaces so that variables are aligned.
231 void dumpRow(ArrayRef<int64_t> row, bool fixedColWidth = true) const;
232
233protected:
235
236 /// Compute an explicit representation for local vars. For all systems coming
237 /// from MLIR integer sets, maps, or expressions where local vars were
238 /// introduced to model floordivs and mods, this always succeeds.
240 MLIRContext *context) const;
241
242 /// Given an affine map that is aligned with this constraint system:
243 /// * Flatten the map.
244 /// * Add newly introduced local columns at the beginning of this constraint
245 /// system (local column pos 0).
246 /// * Add equalities that define the new local columns to this constraint
247 /// system.
248 /// * Return the flattened expressions via `flattenedExprs`.
249 ///
250 /// Note: This is a shared helper function of `addLowerOrUpperBound` and
251 /// `composeMatchingMap`.
253 AffineMap map, std::vector<SmallVector<int64_t, 8>> *flattenedExprs,
254 bool addConservativeSemiAffineBounds = false);
255
256 /// Prints the number of constraints, dimensions, symbols and locals in the
257 /// FlatLinearConstraints. Also, prints for each variable whether there is
258 /// an SSA Value attached to it.
259 void printSpace(raw_ostream &os) const override;
260};
261
262/// FlatLinearValueConstraints represents an extension of FlatLinearConstraints
263/// where each non-local variable can have an SSA Value attached to it.
265public:
266 /// The SSA Values attached to each non-local variable are stored as
267 /// identifiers in the constraint system's space.
269
270 /// Constructs a constraint system reserving memory for the specified number
271 /// of constraints and variables. `valArgs` are the optional SSA values
272 /// associated with each dimension/symbol. These must either be empty or match
273 /// the number of dimensions and symbols.
274 FlatLinearValueConstraints(unsigned numReservedInequalities,
275 unsigned numReservedEqualities,
276 unsigned numReservedCols, unsigned numDims,
277 unsigned numSymbols, unsigned numLocals,
278 ArrayRef<std::optional<Value>> valArgs)
279 : FlatLinearConstraints(numReservedInequalities, numReservedEqualities,
280 numReservedCols, numDims, numSymbols, numLocals) {
281 assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
282 for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
283 if (valArgs[i])
284 setValue(i, *valArgs[i]);
285 }
286
287 /// Constructs a constraint system reserving memory for the specified number
288 /// of constraints and variables. `valArgs` are the optional SSA values
289 /// associated with each dimension/symbol. These must either be empty or match
290 /// the number of dimensions and symbols.
291 FlatLinearValueConstraints(unsigned numReservedInequalities,
292 unsigned numReservedEqualities,
293 unsigned numReservedCols, unsigned numDims,
294 unsigned numSymbols, unsigned numLocals,
295 ArrayRef<Value> valArgs)
296 : FlatLinearConstraints(numReservedInequalities, numReservedEqualities,
297 numReservedCols, numDims, numSymbols, numLocals) {
298 assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
299 for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
300 if (valArgs[i])
301 setValue(i, valArgs[i]);
302 }
303
304 /// Constructs a constraint system with the specified number of dimensions
305 /// and symbols. `valArgs` are the optional SSA values associated with each
306 /// dimension/symbol. These must either be empty or match the number of
307 /// dimensions and symbols.
308 FlatLinearValueConstraints(unsigned numDims, unsigned numSymbols,
309 unsigned numLocals,
310 ArrayRef<std::optional<Value>> valArgs)
311 : FlatLinearValueConstraints(/*numReservedInequalities=*/0,
312 /*numReservedEqualities=*/0,
313 /*numReservedCols=*/numDims + numSymbols +
314 numLocals + 1,
315 numDims, numSymbols, numLocals, valArgs) {}
316
317 /// Constructs a constraint system with the specified number of dimensions
318 /// and symbols. `valArgs` are the optional SSA values associated with each
319 /// dimension/symbol. These must either be empty or match the number of
320 /// dimensions and symbols.
321 FlatLinearValueConstraints(unsigned numDims = 0, unsigned numSymbols = 0,
322 unsigned numLocals = 0,
323 ArrayRef<Value> valArgs = {})
324 : FlatLinearValueConstraints(/*numReservedInequalities=*/0,
325 /*numReservedEqualities=*/0,
326 /*numReservedCols=*/numDims + numSymbols +
327 numLocals + 1,
328 numDims, numSymbols, numLocals, valArgs) {}
329
331 ArrayRef<std::optional<Value>> valArgs = {})
332 : FlatLinearConstraints(fac) {
333 if (valArgs.empty())
334 return;
335 assert(valArgs.size() == getNumDimAndSymbolVars());
336 for (unsigned i = 0, e = valArgs.size(); i < e; ++i)
337 if (valArgs[i])
338 setValue(i, *valArgs[i]);
339 }
340
341 /// Creates an affine constraint system from an IntegerSet. Returns failure
342 /// if `set` is semi-affine, as flattening is not implemented for those.
343 static FailureOr<FlatLinearValueConstraints>
344 create(IntegerSet set, ValueRange operands = {});
345
346 /// Return the kind of this object.
347 Kind getKind() const override { return Kind::FlatLinearValueConstraints; }
348
349 static bool classof(const IntegerRelation *cst) {
350 return cst->getKind() >= Kind::FlatLinearValueConstraints &&
351 cst->getKind() <= Kind::FlatAffineRelation;
352 }
353
354 /// Adds a constant bound for the variable associated with the given Value.
355 void addBound(presburger::BoundType type, Value val, int64_t value);
357
358 /// Returns the Value associated with the pos^th variable. Asserts if
359 /// no Value variable was associated.
360 inline Value getValue(unsigned pos) const {
361 assert(pos < getNumDimAndSymbolVars() && "Invalid position");
362 assert(hasValue(pos) && "variable's Value not set");
363 VarKind kind = getVarKindAt(pos);
364 unsigned relativePos = pos - getVarKindOffset(kind);
365 return space.getId(kind, relativePos).getValue<Value>();
366 }
367
368 /// Returns the Values associated with variables in range [start, end).
369 /// Asserts if no Value was associated with one of these variables.
370 inline void getValues(unsigned start, unsigned end,
371 SmallVectorImpl<Value> *values) const {
372 assert(end <= getNumDimAndSymbolVars() && "invalid end position");
373 assert(start <= end && "invalid start position");
374 values->clear();
375 values->reserve(end - start);
376 for (unsigned i = start; i < end; ++i)
377 values->push_back(getValue(i));
378 }
379
382 maybeValues.reserve(getNumDimAndSymbolVars());
383 for (unsigned i = 0, e = getNumDimAndSymbolVars(); i < e; ++i)
384 if (hasValue(i)) {
385 maybeValues.push_back(getValue(i));
386 } else {
387 maybeValues.push_back(std::nullopt);
388 }
389 return maybeValues;
390 }
391
394 assert(kind != VarKind::Local &&
395 "Local variables do not have any value attached to them.");
397 maybeValues.reserve(getNumVarKind(kind));
398 const unsigned offset = space.getVarKindOffset(kind);
399 for (unsigned i = 0, e = getNumVarKind(kind); i < e; ++i) {
400 if (hasValue(offset + i))
401 maybeValues.push_back(getValue(offset + i));
402 else
403 maybeValues.push_back(std::nullopt);
404 }
405 return maybeValues;
406 }
407
408 /// Returns true if the pos^th variable has an associated Value.
409 inline bool hasValue(unsigned pos) const {
410 assert(pos < getNumDimAndSymbolVars() && "Invalid position");
411 VarKind kind = getVarKindAt(pos);
412 unsigned relativePos = pos - getVarKindOffset(kind);
413 return space.getId(kind, relativePos).hasValue();
414 }
415
416 unsigned appendDimVar(ValueRange vals);
418
419 unsigned appendSymbolVar(ValueRange vals);
421
422 unsigned insertDimVar(unsigned pos, ValueRange vals);
424
425 unsigned insertSymbolVar(unsigned pos, ValueRange vals);
427
428 unsigned insertVar(presburger::VarKind kind, unsigned pos,
429 unsigned num = 1) override;
430 unsigned insertVar(presburger::VarKind kind, unsigned pos, ValueRange vals);
431
432 /// Removes variables in the column range [varStart, varLimit), and copies any
433 /// remaining valid data into place, updates member variables, and resizes
434 /// arrays as needed.
435 void removeVarRange(presburger::VarKind kind, unsigned varStart,
436 unsigned varLimit) override;
437 using IntegerPolyhedron::removeVarRange;
438
439 /// Sets the Value associated with the pos^th variable.
440 /// Stores the Value in the space's identifiers.
441 inline void setValue(unsigned pos, Value val) {
442 assert(pos < getNumDimAndSymbolVars() && "invalid var position");
443 VarKind kind = getVarKindAt(pos);
444 unsigned relativePos = pos - getVarKindOffset(kind);
445 space.setId(kind, relativePos, presburger::Identifier(val));
446 }
447
448 /// Sets the Values associated with the variables in the range [start, end).
449 /// The range must contain only dim and symbol variables.
450 void setValues(unsigned start, unsigned end, ArrayRef<Value> values) {
451 assert(end <= getNumVars() && "invalid end position");
452 assert(start <= end && "invalid start position");
453 assert(values.size() == end - start &&
454 "value should be provided for each variable in the range.");
455 for (unsigned i = start; i < end; ++i)
456 setValue(i, values[i - start]);
457 }
458
459 /// Looks up the position of the variable with the specified Value starting
460 /// with variables at offset `offset`. Returns true if found (false
461 /// otherwise). `pos` is set to the (column) position of the variable.
462 bool findVar(Value val, unsigned *pos, unsigned offset = 0) const;
463
464 /// Returns true if a variable with the specified Value exists, false
465 /// otherwise.
466 bool containsVar(Value val) const;
467
468 /// Projects out the variable that is associate with Value.
469 void projectOut(Value val);
470 using IntegerPolyhedron::projectOut;
471
472 /// Prints the number of constraints, dimensions, symbols and locals in the
473 /// FlatAffineValueConstraints. Also, prints for each variable whether there
474 /// is an SSA Value attached to it.
475 void printSpace(raw_ostream &os) const override;
476
477 /// Align `map` with this constraint system based on `operands`. Each operand
478 /// must already have a corresponding dim/symbol in this constraint system.
479 AffineMap computeAlignedMap(AffineMap map, ValueRange operands) const;
480
481 /// Merge and align the variables of `this` and `other` starting at
482 /// `offset`, so that both constraint systems get the union of the contained
483 /// variables that is dimension-wise and symbol-wise unique; both
484 /// constraint systems are updated so that they have the union of all
485 /// variables, with `this`'s original variables appearing first followed
486 /// by any of `other`'s variables that didn't appear in `this`. Local
487 /// variables in `other` that have the same division representation as local
488 /// variables in `this` are merged into one.
489 // E.g.: Input: `this` has (%i, %j) [%M, %N]
490 // `other` has (%k, %j) [%P, %N, %M]
491 // Output: both `this`, `other` have (%i, %j, %k) [%M, %N, %P]
492 //
493 void mergeAndAlignVarsWithOther(unsigned offset,
495
496 /// Merge and align symbols of `this` and `other` such that both get union of
497 /// of symbols that are unique. Symbols in `this` and `other` should be
498 /// unique. Symbols with Value as `None` are considered to be inequal to all
499 /// other symbols.
501
502 /// Returns true if this constraint system and `other` are in the same
503 /// space, i.e., if they are associated with the same set of variables,
504 /// appearing in the same order. Returns false otherwise.
506
507 /// Updates the constraints to be the smallest bounding (enclosing) box that
508 /// contains the points of `this` set and that of `other`, with the symbols
509 /// being treated specially. For each of the dimensions, the min of the lower
510 /// bounds (symbolic) and the max of the upper bounds (symbolic) is computed
511 /// to determine such a bounding box. `other` is expected to have the same
512 /// dimensional variables as this constraint system (in the same order).
513 ///
514 /// E.g.:
515 /// 1) this = {0 <= d0 <= 127},
516 /// other = {16 <= d0 <= 192},
517 /// output = {0 <= d0 <= 192}
518 /// 2) this = {s0 + 5 <= d0 <= s0 + 20},
519 /// other = {s0 + 1 <= d0 <= s0 + 9},
520 /// output = {s0 + 1 <= d0 <= s0 + 20}
521 /// 3) this = {0 <= d0 <= 5, 1 <= d1 <= 9}
522 /// other = {2 <= d0 <= 6, 5 <= d1 <= 15},
523 /// output = {0 <= d0 <= 6, 1 <= d1 <= 15}
524 LogicalResult unionBoundingBox(const FlatLinearValueConstraints &other);
525 using IntegerPolyhedron::unionBoundingBox;
526
527protected:
528 /// Creates an affine constraint system from an IntegerSet. `error` is set to
529 /// true if `set` could not be flattened, in which case the constraint system
530 /// is left without the constraints of `set`. Use `create` instead.
531 FlatLinearValueConstraints(IntegerSet set, ValueRange operands, bool *error);
532};
533
534/// Flattens 'expr' into 'flattenedExpr', which contains the coefficients of the
535/// dimensions, symbols, and additional variables that represent floor divisions
536/// of dimensions, symbols, and in turn other floor divisions. Returns failure
537/// if 'expr' could not be flattened (i.e., an unhandled semi-affine was found).
538/// 'cst' contains constraints that connect newly introduced local variables
539/// to existing dimensional and symbolic variables. See documentation for
540/// AffineExprFlattener on how mod's and div's are flattened.
541LogicalResult
542getFlattenedAffineExpr(AffineExpr expr, unsigned numDims, unsigned numSymbols,
543 SmallVectorImpl<int64_t> *flattenedExpr,
544 FlatLinearConstraints *cst = nullptr,
545 bool addConservativeSemiAffineBounds = false);
546
547/// Flattens the result expressions of the map to their corresponding flattened
548/// forms and set in 'flattenedExprs'. Returns failure if any expression in the
549/// map could not be flattened (i.e., an unhandled semi-affine was found). 'cst'
550/// contains constraints that connect newly introduced local variables to
551/// existing dimensional and / symbolic variables. See documentation for
552/// AffineExprFlattener on how mod's and div's are flattened. For all affine
553/// expressions that share the same operands (like those of an affine map), this
554/// method should be used instead of repeatedly calling getFlattenedAffineExpr
555/// since local variables added to deal with div's and mod's will be reused
556/// across expressions.
557LogicalResult
558getFlattenedAffineExprs(AffineMap map,
559 std::vector<SmallVector<int64_t, 8>> *flattenedExprs,
560 FlatLinearConstraints *cst = nullptr,
561 bool addConservativeSemiAffineBounds = false);
562LogicalResult
563getFlattenedAffineExprs(IntegerSet set,
564 std::vector<SmallVector<int64_t, 8>> *flattenedExprs,
565 FlatLinearConstraints *cst = nullptr);
566
567LogicalResult
569 presburger::MultiAffineFunction &multiAff);
570
571/// Re-indexes the dimensions and symbols of an affine map with given `operands`
572/// values to align with `dims` and `syms` values.
573///
574/// Each dimension/symbol of the map, bound to an operand `o`, is replaced with
575/// dimension `i`, where `i` is the position of `o` within `dims`. If `o` is not
576/// in `dims`, replace it with symbol `i`, where `i` is the position of `o`
577/// within `syms`. If `o` is not in `syms` either, replace it with a new symbol.
578///
579/// Note: If a value appears multiple times as a dimension/symbol (or both), all
580/// corresponding dim/sym expressions are replaced with the first dimension
581/// bound to that value (or first symbol if no such dimension exists).
582///
583/// The resulting affine map has `dims.size()` many dimensions and at least
584/// `syms.size()` many symbols.
585///
586/// The SSA values of the symbols of the resulting map are optionally returned
587/// via `newSyms`. This is a concatenation of `syms` with the SSA values of the
588/// newly added symbols.
589///
590/// Note: As part of this re-indexing, dimensions may turn into symbols, or vice
591/// versa.
592AffineMap alignAffineMapWithValues(AffineMap map, ValueRange operands,
593 ValueRange dims, ValueRange syms,
594 SmallVector<Value> *newSyms = nullptr);
595
596} // namespace mlir
597
598#endif // MLIR_ANALYSIS_FLATLINEARVALUECONSTRAINTS_H
if(failed(verifyVectorMemoryOp(getOperation(), memrefType, getVectorType()))) return failure()
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition AffineMap.h:46
FlatLinearConstraints is an extension of IntegerPolyhedron.
unsigned appendDimVar(unsigned num=1)
Append variables of the specified kind after the last variable of that kind.
IntegerSet getAsIntegerSet(MLIRContext *context) const
Returns the constraint system as an integer set.
void getSliceBounds(unsigned offset, unsigned num, MLIRContext *context, SmallVectorImpl< AffineMap > *lbMaps, SmallVectorImpl< AffineMap > *ubMaps, bool closedUB=false, bool allowMultiResultUB=false)
Computes the lower and upper bounds of the first num dimensional variables (starting at offset) as an...
FlatLinearConstraints(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, unsigned numDims, unsigned numSymbols, unsigned numLocals)
Constructs a constraint system reserving memory for the specified number of constraints and variables...
FlatLinearConstraints(unsigned numDims=0, unsigned numSymbols=0, unsigned numLocals=0)
Constructs a constraint system with the specified number of dimensions and symbols.
unsigned insertSymbolVar(unsigned pos, unsigned num=1)
unsigned appendLocalVar(unsigned num=1)
void printSpace(raw_ostream &os) const override
Prints the number of constraints, dimensions, symbols and locals in the FlatLinearConstraints.
void dumpRow(ArrayRef< int64_t > row, bool fixedColWidth=true) const
An easier to read dump of a row of the same width as the number of columns.
FlatLinearConstraints(const IntegerPolyhedron &fac)
void dumpPretty() const
A more human-readable version of dump().
AddConservativeSemiAffineBounds
Flag to control if conservative semi-affine bounds should be added in addBound().
LogicalResult composeMatchingMap(AffineMap other)
Composes an affine map whose dimensions and symbols match one to one with the dimensions and symbols ...
unsigned appendSymbolVar(unsigned num=1)
LogicalResult flattenAlignedMapAndMergeLocals(AffineMap map, std::vector< SmallVector< int64_t, 8 > > *flattenedExprs, bool addConservativeSemiAffineBounds=false)
Given an affine map that is aligned with this constraint system:
LogicalResult addBound(presburger::BoundType type, unsigned pos, AffineMap boundMap, bool isClosedBound, AddConservativeSemiAffineBounds=AddConservativeSemiAffineBounds::No)
Adds a bound for the variable at the specified position with constraints being drawn from the specifi...
std::pair< AffineMap, AffineMap > getLowerAndUpperBound(unsigned pos, unsigned offset, unsigned num, unsigned symStartPos, ArrayRef< AffineExpr > localExprs, MLIRContext *context, bool closedUB=false) const
Gets the lower and upper bound of the offset + posth variable treating [0, offset) U [offset + num,...
unsigned insertLocalVar(unsigned pos, unsigned num=1)
LogicalResult computeLocalVars(SmallVectorImpl< AffineExpr > &memo, MLIRContext *context) const
Compute an explicit representation for local vars.
Kind getKind() const override
Return the kind of this object.
unsigned insertDimVar(unsigned pos, unsigned num=1)
Insert variables of the specified kind at position pos.
std::optional< int64_t > getConstantBoundOnDimSize(MLIRContext *context, unsigned pos, AffineMap *lb=nullptr, AffineMap *ub=nullptr, unsigned *minLbPos=nullptr, unsigned *minUbPos=nullptr) const
Returns a non-negative constant bound on the extent (upper bound - lower bound) of the specified vari...
FlatLinearValueConstraints represents an extension of FlatLinearConstraints where each non-local vari...
unsigned insertDimVar(unsigned pos, ValueRange vals)
FlatLinearValueConstraints(unsigned numDims=0, unsigned numSymbols=0, unsigned numLocals=0, ArrayRef< Value > valArgs={})
Constructs a constraint system with the specified number of dimensions and symbols.
LogicalResult unionBoundingBox(const FlatLinearValueConstraints &other)
Updates the constraints to be the smallest bounding (enclosing) box that contains the points of this ...
void mergeAndAlignVarsWithOther(unsigned offset, FlatLinearValueConstraints *other)
Merge and align the variables of this and other starting at offset, so that both constraint systems g...
static FailureOr< FlatLinearValueConstraints > create(IntegerSet set, ValueRange operands={})
Creates an affine constraint system from an IntegerSet.
bool hasValue(unsigned pos) const
Returns true if the pos^th variable has an associated Value.
static bool classof(const IntegerRelation *cst)
presburger::Identifier Identifier
The SSA Values attached to each non-local variable are stored as identifiers in the constraint system...
FlatLinearValueConstraints(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, unsigned numDims, unsigned numSymbols, unsigned numLocals, ArrayRef< Value > valArgs)
Constructs a constraint system reserving memory for the specified number of constraints and variables...
FlatLinearValueConstraints(const IntegerPolyhedron &fac, ArrayRef< std::optional< Value > > valArgs={})
Value getValue(unsigned pos) const
Returns the Value associated with the pos^th variable.
void printSpace(raw_ostream &os) const override
Prints the number of constraints, dimensions, symbols and locals in the FlatAffineValueConstraints.
void mergeSymbolVars(FlatLinearValueConstraints &other)
Merge and align symbols of this and other such that both get union of of symbols that are unique.
FlatLinearValueConstraints(unsigned numDims, unsigned numSymbols, unsigned numLocals, ArrayRef< std::optional< Value > > valArgs)
Constructs a constraint system with the specified number of dimensions and symbols.
void projectOut(Value val)
Projects out the variable that is associate with Value.
bool containsVar(Value val) const
Returns true if a variable with the specified Value exists, false otherwise.
void removeVarRange(presburger::VarKind kind, unsigned varStart, unsigned varLimit) override
Removes variables in the column range [varStart, varLimit), and copies any remaining valid data into ...
void addBound(presburger::BoundType type, Value val, int64_t value)
Adds a constant bound for the variable associated with the given Value.
FlatLinearValueConstraints(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, unsigned numDims, unsigned numSymbols, unsigned numLocals, ArrayRef< std::optional< Value > > valArgs)
Constructs a constraint system reserving memory for the specified number of constraints and variables...
unsigned insertSymbolVar(unsigned pos, ValueRange vals)
bool findVar(Value val, unsigned *pos, unsigned offset=0) const
Looks up the position of the variable with the specified Value starting with variables at offset offs...
bool areVarsAlignedWithOther(const FlatLinearConstraints &other)
Returns true if this constraint system and other are in the same space, i.e., if they are associated ...
AffineMap computeAlignedMap(AffineMap map, ValueRange operands) const
Align map with this constraint system based on operands.
void getValues(unsigned start, unsigned end, SmallVectorImpl< Value > *values) const
Returns the Values associated with variables in range [start, end).
void setValue(unsigned pos, Value val)
Sets the Value associated with the pos^th variable.
SmallVector< std::optional< Value > > getMaybeValues() const
SmallVector< std::optional< Value > > getMaybeValues(presburger::VarKind kind) const
unsigned insertVar(presburger::VarKind kind, unsigned pos, unsigned num=1) override
Insert num variables of the specified kind at position pos.
Kind getKind() const override
Return the kind of this object.
void setValues(unsigned start, unsigned end, ArrayRef< Value > values)
Sets the Values associated with the variables in the range [start, end).
An integer set representing a conjunction of one or more affine equalities and inequalities.
Definition IntegerSet.h:44
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:389
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
An Identifier stores a pointer to an object, such as a Value or an Operation.
An IntegerPolyhedron represents the set of points from a PresburgerSpace that satisfy a list of affin...
unsigned insertVar(VarKind kind, unsigned pos, unsigned num=1) override
Insert num variables of the specified kind at position pos.
IntegerPolyhedron(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, const PresburgerSpace &space)
Constructs a set reserving memory for the specified number of constraints and variables.
Kind
All derived classes of IntegerRelation.
unsigned getNumVarKind(VarKind kind) const
Get the number of vars of the specified kind.
unsigned appendVar(VarKind kind, unsigned num=1)
Append num variables of the specified kind after the last variable of that kind.
VarKind getVarKindAt(unsigned pos) const
Return the VarKind of the var at the specified position.
IntegerRelation(unsigned numReservedInequalities, unsigned numReservedEqualities, unsigned numReservedCols, const PresburgerSpace &space)
Constructs a relation reserving memory for the specified number of constraints and variables.
unsigned getVarKindOffset(VarKind kind) const
Return the index at which the specified kind of vars starts.
This class represents a multi-affine function with the domain as Z^d, where d is the number of domain...
BoundType
The type of bound: equal, lower bound or upper bound.
VarKind
Kind of variable.
Include the generated interface declarations.
AffineMap alignAffineMapWithValues(AffineMap map, ValueRange operands, ValueRange dims, ValueRange syms, SmallVector< Value > *newSyms=nullptr)
Re-indexes the dimensions and symbols of an affine map with given operands values to align with dims ...
LogicalResult getFlattenedAffineExprs(AffineMap map, std::vector< SmallVector< int64_t, 8 > > *flattenedExprs, FlatLinearConstraints *cst=nullptr, bool addConservativeSemiAffineBounds=false)
Flattens the result expressions of the map to their corresponding flattened forms and set in 'flatten...
LogicalResult getFlattenedAffineExpr(AffineExpr expr, unsigned numDims, unsigned numSymbols, SmallVectorImpl< int64_t > *flattenedExpr, FlatLinearConstraints *cst=nullptr, bool addConservativeSemiAffineBounds=false)
Flattens 'expr' into 'flattenedExpr', which contains the coefficients of the dimensions,...
LogicalResult getMultiAffineFunctionFromMap(AffineMap map, presburger::MultiAffineFunction &multiAff)
A mutable affine map. Its affine expressions are however unique.
Definition AffineMap.h:430