MLIR  21.0.0git
ValueBoundsOpInterface.h
Go to the documentation of this file.
1 //===- ValueBoundsOpInterface.h - Value Bounds ------------------*- 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_INTERFACES_VALUEBOUNDSOPINTERFACE_H_
10 #define MLIR_INTERFACES_VALUEBOUNDSOPINTERFACE_H_
11 
13 #include "mlir/IR/Builders.h"
14 #include "mlir/IR/OpDefinition.h"
15 #include "mlir/IR/Value.h"
17 #include "llvm/ADT/SetVector.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Support/ExtensibleRTTI.h"
20 
21 #include <queue>
22 
23 namespace mlir {
24 class OffsetSizeAndStrideOpInterface;
25 
26 /// A hyperrectangular slice, represented as a list of offsets, sizes and
27 /// strides.
29 public:
32  ArrayRef<OpFoldResult> strides);
33 
34  /// Create a hyperrectangular slice with unit strides.
37 
38  /// Infer a hyperrectangular slice from `OffsetSizeAndStrideOpInterface`.
39  HyperrectangularSlice(OffsetSizeAndStrideOpInterface op);
40 
41  ArrayRef<OpFoldResult> getMixedOffsets() const { return mixedOffsets; }
42  ArrayRef<OpFoldResult> getMixedSizes() const { return mixedSizes; }
43  ArrayRef<OpFoldResult> getMixedStrides() const { return mixedStrides; }
44 
45 private:
46  SmallVector<OpFoldResult> mixedOffsets;
47  SmallVector<OpFoldResult> mixedSizes;
48  SmallVector<OpFoldResult> mixedStrides;
49 };
50 
52 
53 /// A helper class to be used with `ValueBoundsOpInterface`. This class stores a
54 /// constraint system and mapping of constrained variables to index-typed
55 /// values or dimension sizes of shaped values.
56 ///
57 /// Interface implementations of `ValueBoundsOpInterface` use `addBounds` to
58 /// insert constraints about their results and/or region block arguments into
59 /// the constraint set in the form of an AffineExpr. When a bound should be
60 /// expressed in terms of another value/dimension, `getExpr` can be used to
61 /// retrieve an AffineExpr that represents the specified value/dimension.
62 ///
63 /// When a value/dimension is retrieved for the first time through `getExpr`,
64 /// it is added to an internal worklist. See `computeBound` for more details.
65 ///
66 /// Note: Any modification of existing IR invalides the data stored in this
67 /// class. Adding new operations is allowed.
69  : public llvm::RTTIExtends<ValueBoundsConstraintSet, llvm::RTTIRoot> {
70 protected:
71  /// Helper class that builds a bound for a shaped value dimension or
72  /// index-typed value.
73  class BoundBuilder {
74  public:
75  /// Specify a dimension, assuming that the underlying value is a shaped
76  /// value.
77  BoundBuilder &operator[](int64_t dim);
78 
79  // These overloaded operators add lower/upper/equality bounds.
80  void operator<(AffineExpr expr);
81  void operator<=(AffineExpr expr);
82  void operator>(AffineExpr expr);
83  void operator>=(AffineExpr expr);
84  void operator==(AffineExpr expr);
85  void operator<(OpFoldResult ofr);
86  void operator<=(OpFoldResult ofr);
87  void operator>(OpFoldResult ofr);
88  void operator>=(OpFoldResult ofr);
89  void operator==(OpFoldResult ofr);
90  void operator<(int64_t i);
91  void operator<=(int64_t i);
92  void operator>(int64_t i);
93  void operator>=(int64_t i);
94  void operator==(int64_t i);
95 
96  protected:
99  : cstr(cstr), value(value) {}
100 
101  private:
102  BoundBuilder(const BoundBuilder &) = delete;
103  BoundBuilder &operator=(const BoundBuilder &) = delete;
104  bool operator==(const BoundBuilder &) = delete;
105  bool operator!=(const BoundBuilder &) = delete;
106 
108  Value value;
109  std::optional<int64_t> dim;
110  };
111 
112 public:
113  static char ID;
114 
115  /// A variable that can be added to the constraint set as a "column". The
116  /// value bounds infrastructure can compute bounds for variables and compare
117  /// two variables.
118  ///
119  /// Internally, a variable is represented as an affine map and operands.
120  class Variable {
121  public:
122  /// Construct a variable for an index-typed attribute or SSA value.
123  Variable(OpFoldResult ofr);
124 
125  /// Construct a variable for an index-typed SSA value.
126  Variable(Value indexValue);
127 
128  /// Construct a variable for a dimension of a shaped value.
129  Variable(Value shapedValue, int64_t dim);
130 
131  /// Construct a variable for an index-typed attribute/SSA value or for a
132  /// dimension of a shaped value. A non-null dimension must be provided if
133  /// and only if `ofr` is a shaped value.
134  Variable(OpFoldResult ofr, std::optional<int64_t> dim);
135 
136  /// Construct a variable for a map and its operands.
137  Variable(AffineMap map, ArrayRef<Variable> mapOperands);
138  Variable(AffineMap map, ValueRange mapOperands);
139 
140  MLIRContext *getContext() const { return map.getContext(); }
141 
142  /// Returns the affine map.
143  AffineMap getMap() const { return map; }
144 
145  /// Returns the map operands.
146  ValueDimList &getOperands() { return mapOperands; }
147  const ValueDimList &getOperands() const { return mapOperands; }
148 
149  private:
151  AffineMap map;
152  ValueDimList mapOperands;
153  };
154 
155  /// The stop condition when traversing the backward slice of a shaped value/
156  /// index-type value. The traversal continues until the stop condition
157  /// evaluates to "true" for a value.
158  ///
159  /// The first parameter of the function is the shaped value/index-typed
160  /// value. The second parameter is the dimension in case of a shaped value.
161  /// The third parameter is this constraint set.
162  using StopConditionFn = std::function<bool(
163  Value, std::optional<int64_t> /*dim*/, ValueBoundsConstraintSet &cstr)>;
164 
165  /// Compute a bound for the given variable. The computed bound is stored in
166  /// `resultMap`. The operands of the bound are stored in `mapOperands`. An
167  /// operand is either an index-type SSA value or a shaped value and a
168  /// dimension.
169  ///
170  /// The bound is computed in terms of values/dimensions for which
171  /// `stopCondition` evaluates to "true". To that end, the backward slice
172  /// (reverse use-def chain) of the given value is visited in a worklist-driven
173  /// manner and the constraint set is populated according to
174  /// `ValueBoundsOpInterface` for each visited value.
175  ///
176  /// By default, lower/equal bounds are closed and upper bounds are open. If
177  /// `closedUB` is set to "true", upper bounds are also closed.
178  static LogicalResult
179  computeBound(AffineMap &resultMap, ValueDimList &mapOperands,
180  presburger::BoundType type, const Variable &var,
181  StopConditionFn stopCondition, bool closedUB = false);
182 
183  /// Compute a bound in terms of the values/dimensions in `dependencies`. The
184  /// computed bound consists of only constant terms and dependent values (or
185  /// dimension sizes thereof).
186  static LogicalResult
187  computeDependentBound(AffineMap &resultMap, ValueDimList &mapOperands,
188  presburger::BoundType type, const Variable &var,
189  ValueDimList dependencies, bool closedUB = false);
190 
191  /// Compute a bound in that is independent of all values in `independencies`.
192  ///
193  /// Independencies are the opposite of dependencies. The computed bound does
194  /// not contain any SSA values that are part of `independencies`. E.g., this
195  /// function can be used to make ops hoistable from loops. To that end, ops
196  /// must be made independent of loop induction variables (in the case of "for"
197  /// loops). Loop induction variables are the independencies; they may not
198  /// appear in the computed bound.
199  static LogicalResult
200  computeIndependentBound(AffineMap &resultMap, ValueDimList &mapOperands,
201  presburger::BoundType type, const Variable &var,
202  ValueRange independencies, bool closedUB = false);
203 
204  /// Compute a constant bound for the given variable.
205  ///
206  /// This function traverses the backward slice of the given operands in a
207  /// worklist-driven manner until `stopCondition` evaluates to "true". The
208  /// constraint set is populated according to `ValueBoundsOpInterface` for each
209  /// visited value. (No constraints are added for values for which the stop
210  /// condition evaluates to "true".)
211  ///
212  /// The stop condition is optional: If none is specified, the backward slice
213  /// is traversed in a breadth-first manner until a constant bound could be
214  /// computed.
215  ///
216  /// By default, lower/equal bounds are closed and upper bounds are open. If
217  /// `closedUB` is set to "true", upper bounds are also closed.
218  static FailureOr<int64_t>
220  StopConditionFn stopCondition = nullptr,
221  bool closedUB = false);
222 
223  /// Compute a constant delta between the given two values. Return "failure"
224  /// if a constant delta could not be determined.
225  ///
226  /// `dim1`/`dim2` must be `nullopt` if and only if `value1`/`value2` are
227  /// index-typed.
228  static FailureOr<int64_t>
229  computeConstantDelta(Value value1, Value value2,
230  std::optional<int64_t> dim1 = std::nullopt,
231  std::optional<int64_t> dim2 = std::nullopt);
232 
233  /// Traverse the IR starting from the given value/dim and populate constraints
234  /// as long as the stop condition holds. Also process all values/dims that are
235  /// already on the worklist.
236  void populateConstraints(Value value, std::optional<int64_t> dim);
237 
238  /// Comparison operator for `ValueBoundsConstraintSet::compare`.
239  enum ComparisonOperator { LT, LE, EQ, GT, GE };
240 
241  /// Populate constraints for lhs/rhs (until the stop condition is met). Then,
242  /// try to prove that, based on the current state of this constraint set
243  /// (i.e., without analyzing additional IR or adding new constraints), the
244  /// "lhs" value/dim is LE/LT/EQ/GT/GE than the "rhs" value/dim.
245  ///
246  /// Return "true" if the specified relation between the two values/dims was
247  /// proven to hold. Return "false" if the specified relation could not be
248  /// proven. This could be because the specified relation does in fact not hold
249  /// or because there is not enough information in the constraint set. In other
250  /// words, if we do not know for sure, this function returns "false".
251  bool populateAndCompare(const Variable &lhs, ComparisonOperator cmp,
252  const Variable &rhs);
253 
254  /// Return "true" if "lhs cmp rhs" was proven to hold. Return "false" if the
255  /// specified relation could not be proven. This could be because the
256  /// specified relation does in fact not hold or because there is not enough
257  /// information in the constraint set. In other words, if we do not know for
258  /// sure, this function returns "false".
259  ///
260  /// This function keeps traversing the backward slice of lhs/rhs until could
261  /// prove the relation or until it ran out of IR.
262  static bool compare(const Variable &lhs, ComparisonOperator cmp,
263  const Variable &rhs);
264  /// This function is similar to `ValueBoundsConstraintSet::compare`, except
265  /// that it returns false if `!(lhs cmp rhs)`, and `failure` if neither the
266  /// relation nor its inverse relation could be proven.
267  static llvm::FailureOr<bool> strongCompare(const Variable &lhs,
268  ComparisonOperator cmp,
269  const Variable &rhs);
270 
271  /// Compute whether the given variables are equal. Return "failure" if
272  /// equality could not be determined.
273  static FailureOr<bool> areEqual(const Variable &var1, const Variable &var2);
274 
275  /// Return "true" if the given slices are guaranteed to be overlapping.
276  /// Return "false" if the given slices are guaranteed to be non-overlapping.
277  /// Return "failure" if unknown.
278  ///
279  /// Slices are overlapping if for all dimensions:
280  /// * offset1 + size1 * stride1 <= offset2
281  /// * and offset2 + size2 * stride2 <= offset1
282  ///
283  /// Slice are non-overlapping if the above constraint is not satisfied for
284  /// at least one dimension.
285  static FailureOr<bool> areOverlappingSlices(MLIRContext *ctx,
286  HyperrectangularSlice slice1,
287  HyperrectangularSlice slice2);
288 
289  /// Return "true" if the given slices are guaranteed to be equivalent.
290  /// Return "false" if the given slices are guaranteed to be non-equivalent.
291  /// Return "failure" if unknown.
292  ///
293  /// Slices are equivalent if their offsets, sizes and strices are equal.
294  static FailureOr<bool> areEquivalentSlices(MLIRContext *ctx,
295  HyperrectangularSlice slice1,
296  HyperrectangularSlice slice2);
297 
298  /// Add a bound for the given index-typed value or shaped value. This function
299  /// returns a builder that adds the bound.
300  BoundBuilder bound(Value value) { return BoundBuilder(*this, value); }
301 
302  /// Return an expression that represents the given index-typed value or shaped
303  /// value dimension. If this value/dimension was not used so far, it is added
304  /// to the worklist.
305  ///
306  /// `dim` must be `nullopt` if and only if the given value is of index type.
307  AffineExpr getExpr(Value value, std::optional<int64_t> dim = std::nullopt);
308 
309  /// Return an expression that represents a constant or index-typed SSA value.
310  /// In case of a value, if this value was not used so far, it is added to the
311  /// worklist.
313 
314  /// Return an expression that represents a constant.
315  AffineExpr getExpr(int64_t constant);
316 
317  /// Debugging only: Dump the constraint set and the column-to-value/dim
318  /// mapping to llvm::errs.
319  void dump() const;
320 
321 protected:
322  /// Dimension identifier to indicate a value is index-typed. This is used for
323  /// internal data structures/API only.
324  static constexpr int64_t kIndexValue = -1;
325 
326  /// An index-typed value or the dimension of a shaped-type value.
327  using ValueDim = std::pair<Value, int64_t>;
328 
330  bool addConservativeSemiAffineBounds = false);
331 
332  /// Return "true" if, based on the current state of the constraint system,
333  /// "lhs cmp rhs" was proven to hold. Return "false" if the specified relation
334  /// could not be proven. This could be because the specified relation does in
335  /// fact not hold or because there is not enough information in the constraint
336  /// set. In other words, if we do not know for sure, this function returns
337  /// "false".
338  ///
339  /// This function does not analyze any IR and does not populate any additional
340  /// constraints.
341  bool comparePos(int64_t lhsPos, ComparisonOperator cmp, int64_t rhsPos);
342 
343  /// Return "true" if, based on the current state of the constraint system,
344  /// "lhs cmp rhs" was proven to hold. It returns "false" if "!(lhs cmp rhs)"
345  /// can be proven. Otherwise, it returns `failure` if neither the relation nor
346  /// its inverse relation could be proven.
347  ///
348  /// This function does not analyze any IR and does not populate any additional
349  /// constraints.
350  llvm::FailureOr<bool> strongComparePos(int64_t lhsPos, ComparisonOperator cmp,
351  int64_t rhsPos);
352 
353  /// Given an affine map with a single result (and map operands), add a new
354  /// column to the constraint set that represents the result of the map.
355  /// Traverse additional IR starting from the map operands as needed (as long
356  /// as the stop condition is not satisfied). Also process all values/dims that
357  /// are already on the worklist. Return the position of the newly added
358  /// column.
359  int64_t populateConstraints(AffineMap map, ValueDimList mapOperands);
360 
361  /// Iteratively process all elements on the worklist until an index-typed
362  /// value or shaped value meets `stopCondition`. Such values are not processed
363  /// any further.
364  void processWorklist();
365 
366  /// Bound the given column in the underlying constraint set by the given
367  /// expression.
368  void addBound(presburger::BoundType type, int64_t pos, AffineExpr expr);
369 
370  /// Return the column position of the given value/dimension. Asserts that the
371  /// value/dimension exists in the constraint set.
372  int64_t getPos(Value value, std::optional<int64_t> dim = std::nullopt) const;
373 
374  /// Return an affine expression that represents column `pos` in the constraint
375  /// set.
376  AffineExpr getPosExpr(int64_t pos);
377 
378  /// Return "true" if the given value/dim is mapped (i.e., has a corresponding
379  /// column in the constraint system).
380  bool isMapped(Value value, std::optional<int64_t> dim = std::nullopt) const;
381 
382  /// Insert a value/dimension into the constraint set. If `isSymbol` is set to
383  /// "false", a dimension is added. The value/dimension is added to the
384  /// worklist if `addToWorklist` is set.
385  ///
386  /// Note: There are certain affine restrictions wrt. dimensions. E.g., they
387  /// cannot be multiplied. Furthermore, bounds can only be queried for
388  /// dimensions but not for symbols.
389  int64_t insert(Value value, std::optional<int64_t> dim, bool isSymbol = true,
390  bool addToWorklist = true);
391 
392  /// Insert an anonymous column into the constraint set. The column is not
393  /// bound to any value/dimension. If `isSymbol` is set to "false", a dimension
394  /// is added.
395  ///
396  /// Note: There are certain affine restrictions wrt. dimensions. E.g., they
397  /// cannot be multiplied. Furthermore, bounds can only be queried for
398  /// dimensions but not for symbols.
399  int64_t insert(bool isSymbol = true);
400 
401  /// Insert the given affine map and its bound operands as a new column in the
402  /// constraint system. Return the position of the new column. Any operands
403  /// that were not analyzed yet are put on the worklist.
404  int64_t insert(AffineMap map, ValueDimList operands, bool isSymbol = true);
405  int64_t insert(const Variable &var, bool isSymbol = true);
406 
407  /// Project out the given column in the constraint set.
408  void projectOut(int64_t pos);
409 
410  /// Project out all columns for which the condition holds.
411  void projectOut(function_ref<bool(ValueDim)> condition);
412 
413  void projectOutAnonymous(std::optional<int64_t> except = std::nullopt);
414 
415  /// Mapping of columns to values/shape dimensions.
417  /// Reverse mapping of values/shape dimensions to columns.
419 
420  /// Worklist of values/shape dimensions that have not been processed yet.
421  std::queue<int64_t> worklist;
422 
423  /// Constraint system of equalities and inequalities.
425 
426  /// Builder for constructing affine expressions.
428 
429  /// The current stop condition function.
431 
432  /// Should conservative bounds be added for semi-affine expressions.
434 };
435 
436 } // namespace mlir
437 
438 #include "mlir/Interfaces/ValueBoundsOpInterface.h.inc"
439 
440 #endif // MLIR_INTERFACES_VALUEBOUNDSOPINTERFACE_H_
Base type for affine expression.
Definition: AffineExpr.h:68
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition: AffineMap.h:46
MLIRContext * getContext() const
Definition: AffineMap.cpp:343
This class is a general helper class for creating context-global objects like types,...
Definition: Builders.h:50
FlatLinearConstraints is an extension of IntegerPolyhedron.
A hyperrectangular slice, represented as a list of offsets, sizes and strides.
HyperrectangularSlice(ArrayRef< OpFoldResult > offsets, ArrayRef< OpFoldResult > sizes, ArrayRef< OpFoldResult > strides)
ArrayRef< OpFoldResult > getMixedOffsets() const
ArrayRef< OpFoldResult > getMixedSizes() const
ArrayRef< OpFoldResult > getMixedStrides() const
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
This class represents a single result from folding an operation.
Definition: OpDefinition.h:271
Helper class that builds a bound for a shaped value dimension or index-typed value.
BoundBuilder(ValueBoundsConstraintSet &cstr, Value value)
BoundBuilder & operator[](int64_t dim)
Specify a dimension, assuming that the underlying value is a shaped value.
A variable that can be added to the constraint set as a "column".
Variable(OpFoldResult ofr)
Construct a variable for an index-typed attribute or SSA value.
AffineMap getMap() const
Returns the affine map.
ValueDimList & getOperands()
Returns the map operands.
A helper class to be used with ValueBoundsOpInterface.
static bool compare(const Variable &lhs, ComparisonOperator cmp, const Variable &rhs)
Return "true" if "lhs cmp rhs" was proven to hold.
static FailureOr< bool > areEqual(const Variable &var1, const Variable &var2)
Compute whether the given variables are equal.
DenseMap< ValueDim, int64_t > valueDimToPosition
Reverse mapping of values/shape dimensions to columns.
void processWorklist()
Iteratively process all elements on the worklist until an index-typed value or shaped value meets sto...
bool addConservativeSemiAffineBounds
Should conservative bounds be added for semi-affine expressions.
AffineExpr getExpr(Value value, std::optional< int64_t > dim=std::nullopt)
Return an expression that represents the given index-typed value or shaped value dimension.
SmallVector< std::optional< ValueDim > > positionToValueDim
Mapping of columns to values/shape dimensions.
static LogicalResult computeIndependentBound(AffineMap &resultMap, ValueDimList &mapOperands, presburger::BoundType type, const Variable &var, ValueRange independencies, bool closedUB=false)
Compute a bound in that is independent of all values in independencies.
ValueBoundsConstraintSet(MLIRContext *ctx, StopConditionFn stopCondition, bool addConservativeSemiAffineBounds=false)
void projectOut(int64_t pos)
Project out the given column in the constraint set.
static FailureOr< int64_t > computeConstantDelta(Value value1, Value value2, std::optional< int64_t > dim1=std::nullopt, std::optional< int64_t > dim2=std::nullopt)
Compute a constant delta between the given two values.
static llvm::FailureOr< bool > strongCompare(const Variable &lhs, ComparisonOperator cmp, const Variable &rhs)
This function is similar to ValueBoundsConstraintSet::compare, except that it returns false if !...
void addBound(presburger::BoundType type, int64_t pos, AffineExpr expr)
Bound the given column in the underlying constraint set by the given expression.
StopConditionFn stopCondition
The current stop condition function.
ComparisonOperator
Comparison operator for ValueBoundsConstraintSet::compare.
BoundBuilder bound(Value value)
Add a bound for the given index-typed value or shaped value.
static LogicalResult computeBound(AffineMap &resultMap, ValueDimList &mapOperands, presburger::BoundType type, const Variable &var, StopConditionFn stopCondition, bool closedUB=false)
Compute a bound for the given variable.
int64_t getPos(Value value, std::optional< int64_t > dim=std::nullopt) const
Return the column position of the given value/dimension.
int64_t insert(Value value, std::optional< int64_t > dim, bool isSymbol=true, bool addToWorklist=true)
Insert a value/dimension into the constraint set.
bool comparePos(int64_t lhsPos, ComparisonOperator cmp, int64_t rhsPos)
Return "true" if, based on the current state of the constraint system, "lhs cmp rhs" was proven to ho...
static FailureOr< int64_t > computeConstantBound(presburger::BoundType type, const Variable &var, StopConditionFn stopCondition=nullptr, bool closedUB=false)
Compute a constant bound for the given variable.
void dump() const
Debugging only: Dump the constraint set and the column-to-value/dim mapping to llvm::errs.
std::queue< int64_t > worklist
Worklist of values/shape dimensions that have not been processed yet.
FlatLinearConstraints cstr
Constraint system of equalities and inequalities.
bool isMapped(Value value, std::optional< int64_t > dim=std::nullopt) const
Return "true" if the given value/dim is mapped (i.e., has a corresponding column in the constraint sy...
llvm::FailureOr< bool > strongComparePos(int64_t lhsPos, ComparisonOperator cmp, int64_t rhsPos)
Return "true" if, based on the current state of the constraint system, "lhs cmp rhs" was proven to ho...
AffineExpr getPosExpr(int64_t pos)
Return an affine expression that represents column pos in the constraint set.
void projectOutAnonymous(std::optional< int64_t > except=std::nullopt)
static FailureOr< bool > areEquivalentSlices(MLIRContext *ctx, HyperrectangularSlice slice1, HyperrectangularSlice slice2)
Return "true" if the given slices are guaranteed to be equivalent.
std::pair< Value, int64_t > ValueDim
An index-typed value or the dimension of a shaped-type value.
void populateConstraints(Value value, std::optional< int64_t > dim)
Traverse the IR starting from the given value/dim and populate constraints as long as the stop condit...
static FailureOr< bool > areOverlappingSlices(MLIRContext *ctx, HyperrectangularSlice slice1, HyperrectangularSlice slice2)
Return "true" if the given slices are guaranteed to be overlapping.
std::function< bool(Value, std::optional< int64_t >, ValueBoundsConstraintSet &cstr)> StopConditionFn
The stop condition when traversing the backward slice of a shaped value/ index-type value.
Builder builder
Builder for constructing affine expressions.
bool populateAndCompare(const Variable &lhs, ComparisonOperator cmp, const Variable &rhs)
Populate constraints for lhs/rhs (until the stop condition is met).
static constexpr int64_t kIndexValue
Dimension identifier to indicate a value is index-typed.
static LogicalResult computeDependentBound(AffineMap &resultMap, ValueDimList &mapOperands, presburger::BoundType type, const Variable &var, ValueDimList dependencies, bool closedUB=false)
Compute a bound in terms of the values/dimensions in dependencies.
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:387
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
BoundType
The type of bound: equal, lower bound or upper bound.
bool operator!=(const Fraction &x, const Fraction &y)
Definition: Fraction.h:95
Include the generated interface declarations.
SmallVector< std::pair< Value, std::optional< int64_t > >> ValueDimList