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