MLIR  19.0.0git
AffineExpr.h
Go to the documentation of this file.
1 //===- AffineExpr.h - MLIR Affine Expr Class --------------------*- 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 // An affine expression is an affine combination of dimension identifiers and
10 // symbols, including ceildiv/floordiv/mod by a constant integer.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_IR_AFFINEEXPR_H
15 #define MLIR_IR_AFFINEEXPR_H
16 
17 #include "mlir/IR/Visitors.h"
18 #include "mlir/Support/LLVM.h"
19 #include "llvm/ADT/DenseMapInfo.h"
20 #include "llvm/ADT/Hashing.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/Support/Casting.h"
23 #include <functional>
24 #include <type_traits>
25 
26 namespace mlir {
27 
28 class MLIRContext;
29 class AffineMap;
30 class IntegerSet;
31 
32 namespace detail {
33 
34 struct AffineExprStorage;
35 struct AffineBinaryOpExprStorage;
36 struct AffineDimExprStorage;
37 struct AffineConstantExprStorage;
38 
39 } // namespace detail
40 
41 enum class AffineExprKind {
42  Add,
43  /// RHS of mul is always a constant or a symbolic expression.
44  Mul,
45  /// RHS of mod is always a constant or a symbolic expression with a positive
46  /// value.
47  Mod,
48  /// RHS of floordiv is always a constant or a symbolic expression.
49  FloorDiv,
50  /// RHS of ceildiv is always a constant or a symbolic expression.
51  CeilDiv,
52 
53  /// This is a marker for the last affine binary op. The range of binary
54  /// op's is expected to be this element and earlier.
56 
57  /// Constant integer.
58  Constant,
59  /// Dimensional identifier.
60  DimId,
61  /// Symbolic identifier.
62  SymbolId,
63 };
64 
65 /// Base type for affine expression.
66 /// AffineExpr's are immutable value types with intuitive operators to
67 /// operate on chainable, lightweight compositions.
68 /// An AffineExpr is an interface to the underlying storage type pointer.
69 class AffineExpr {
70 public:
72 
73  constexpr AffineExpr() {}
74  /* implicit */ AffineExpr(const ImplType *expr)
75  : expr(const_cast<ImplType *>(expr)) {}
76 
77  bool operator==(AffineExpr other) const { return expr == other.expr; }
78  bool operator!=(AffineExpr other) const { return !(*this == other); }
79  bool operator==(int64_t v) const;
80  bool operator!=(int64_t v) const { return !(*this == v); }
81  explicit operator bool() const { return expr; }
82 
83  bool operator!() const { return expr == nullptr; }
84 
85  template <typename U>
86  [[deprecated("Use llvm::isa<U>() instead")]] constexpr bool isa() const;
87 
88  template <typename U>
89  [[deprecated("Use llvm::dyn_cast<U>() instead")]] U dyn_cast() const;
90 
91  template <typename U>
92  [[deprecated("Use llvm::dyn_cast_or_null<U>() instead")]] U
93  dyn_cast_or_null() const;
94 
95  template <typename U>
96  [[deprecated("Use llvm::cast<U>() instead")]] U cast() const;
97 
98  MLIRContext *getContext() const;
99 
100  /// Return the classification for this type.
101  AffineExprKind getKind() const;
102 
103  void print(raw_ostream &os) const;
104  void dump() const;
105 
106  /// Returns true if this expression is made out of only symbols and
107  /// constants, i.e., it does not involve dimensional identifiers.
108  bool isSymbolicOrConstant() const;
109 
110  /// Returns true if this is a pure affine expression, i.e., multiplication,
111  /// floordiv, ceildiv, and mod is only allowed w.r.t constants.
112  bool isPureAffine() const;
113 
114  /// Returns the greatest known integral divisor of this affine expression. The
115  /// result is always positive.
116  int64_t getLargestKnownDivisor() const;
117 
118  /// Return true if the affine expression is a multiple of 'factor'.
119  bool isMultipleOf(int64_t factor) const;
120 
121  /// Return true if the affine expression involves AffineDimExpr `position`.
122  bool isFunctionOfDim(unsigned position) const;
123 
124  /// Return true if the affine expression involves AffineSymbolExpr `position`.
125  bool isFunctionOfSymbol(unsigned position) const;
126 
127  /// Walk all of the AffineExpr's in this expression in postorder. This allows
128  /// a lambda walk function that can either return `void` or a WalkResult. With
129  /// a WalkResult, interrupting is supported.
130  template <typename FnT, typename RetT = detail::walkResultType<FnT>>
131  RetT walk(FnT &&callback) const {
132  return walk<RetT>(*this, callback);
133  }
134 
135  /// This method substitutes any uses of dimensions and symbols (e.g.
136  /// dim#0 with dimReplacements[0]) and returns the modified expression tree.
137  /// This is a dense replacement method: a replacement must be specified for
138  /// every single dim and symbol.
140  ArrayRef<AffineExpr> symReplacements) const;
141 
142  /// Dim-only version of replaceDimsAndSymbols.
143  AffineExpr replaceDims(ArrayRef<AffineExpr> dimReplacements) const;
144 
145  /// Symbol-only version of replaceDimsAndSymbols.
146  AffineExpr replaceSymbols(ArrayRef<AffineExpr> symReplacements) const;
147 
148  /// Sparse replace method. Replace `expr` by `replacement` and return the
149  /// modified expression tree.
150  AffineExpr replace(AffineExpr expr, AffineExpr replacement) const;
151 
152  /// Sparse replace method. If `*this` appears in `map` replaces it by
153  /// `map[*this]` and return the modified expression tree. Otherwise traverse
154  /// `*this` and apply replace with `map` on its subexpressions.
156 
157  /// Replace dims[offset ... numDims)
158  /// by dims[offset + shift ... shift + numDims).
159  AffineExpr shiftDims(unsigned numDims, unsigned shift,
160  unsigned offset = 0) const;
161 
162  /// Replace symbols[offset ... numSymbols)
163  /// by symbols[offset + shift ... shift + numSymbols).
164  AffineExpr shiftSymbols(unsigned numSymbols, unsigned shift,
165  unsigned offset = 0) const;
166 
167  AffineExpr operator+(int64_t v) const;
168  AffineExpr operator+(AffineExpr other) const;
169  AffineExpr operator-() const;
170  AffineExpr operator-(int64_t v) const;
171  AffineExpr operator-(AffineExpr other) const;
172  AffineExpr operator*(int64_t v) const;
173  AffineExpr operator*(AffineExpr other) const;
174  AffineExpr floorDiv(uint64_t v) const;
175  AffineExpr floorDiv(AffineExpr other) const;
176  AffineExpr ceilDiv(uint64_t v) const;
177  AffineExpr ceilDiv(AffineExpr other) const;
178  AffineExpr operator%(uint64_t v) const;
179  AffineExpr operator%(AffineExpr other) const;
180 
181  /// Compose with an AffineMap.
182  /// Returns the composition of this AffineExpr with `map`.
183  ///
184  /// Prerequisites:
185  /// `this` and `map` are composable, i.e. that the number of AffineDimExpr of
186  /// `this` is smaller than the number of results of `map`. If a result of a
187  /// map does not have a corresponding AffineDimExpr, that result simply does
188  /// not appear in the produced AffineExpr.
189  ///
190  /// Example:
191  /// expr: `d0 + d2`
192  /// map: `(d0, d1, d2)[s0, s1] -> (d0 + s1, d1 + s0, d0 + d1 + d2)`
193  /// returned expr: `d0 * 2 + d1 + d2 + s1`
194  AffineExpr compose(AffineMap map) const;
195 
196  friend ::llvm::hash_code hash_value(AffineExpr arg);
197 
198  /// Methods supporting C API.
199  const void *getAsOpaquePointer() const {
200  return static_cast<const void *>(expr);
201  }
202  static AffineExpr getFromOpaquePointer(const void *pointer) {
203  return AffineExpr(
204  reinterpret_cast<ImplType *>(const_cast<void *>(pointer)));
205  }
206 
207  ImplType *getImpl() const { return expr; }
208 
209 protected:
210  ImplType *expr{nullptr};
211 
212 private:
213  /// A trampoline for the templated non-static AffineExpr::walk method to
214  /// dispatch lambda `callback`'s of either a void result type or a
215  /// WalkResult type. Walk all of the AffineExprs in `e` in postorder. Users
216  /// should use the regular (non-static) `walk` method.
217  template <typename WalkRetTy>
218  static WalkRetTy walk(AffineExpr e,
219  function_ref<WalkRetTy(AffineExpr)> callback);
220 };
221 
222 /// Affine binary operation expression. An affine binary operation could be an
223 /// add, mul, floordiv, ceildiv, or a modulo operation. (Subtraction is
224 /// represented through a multiply by -1 and add.) These expressions are always
225 /// constructed in a simplified form. For eg., the LHS and RHS operands can't
226 /// both be constants. There are additional canonicalizing rules depending on
227 /// the op type: see checks in the constructor.
229 public:
231  /* implicit */ AffineBinaryOpExpr(AffineExpr::ImplType *ptr);
232  AffineExpr getLHS() const;
233  AffineExpr getRHS() const;
234 };
235 
236 /// A dimensional identifier appearing in an affine expression.
237 class AffineDimExpr : public AffineExpr {
238 public:
240  /* implicit */ AffineDimExpr(AffineExpr::ImplType *ptr);
241  unsigned getPosition() const;
242 };
243 
244 /// A symbolic identifier appearing in an affine expression.
245 class AffineSymbolExpr : public AffineExpr {
246 public:
248  /* implicit */ AffineSymbolExpr(AffineExpr::ImplType *ptr);
249  unsigned getPosition() const;
250 };
251 
252 /// An integer constant appearing in affine expression.
254 public:
256  /* implicit */ AffineConstantExpr(AffineExpr::ImplType *ptr = nullptr);
257  int64_t getValue() const;
258 };
259 
260 /// Make AffineExpr hashable.
261 inline ::llvm::hash_code hash_value(AffineExpr arg) {
263 }
264 
265 inline AffineExpr operator+(int64_t val, AffineExpr expr) { return expr + val; }
266 inline AffineExpr operator*(int64_t val, AffineExpr expr) { return expr * val; }
267 inline AffineExpr operator-(int64_t val, AffineExpr expr) {
268  return expr * (-1) + val;
269 }
270 
271 /// These free functions allow clients of the API to not use classes in detail.
272 AffineExpr getAffineDimExpr(unsigned position, MLIRContext *context);
273 AffineExpr getAffineSymbolExpr(unsigned position, MLIRContext *context);
274 AffineExpr getAffineConstantExpr(int64_t constant, MLIRContext *context);
275 SmallVector<AffineExpr> getAffineConstantExprs(ArrayRef<int64_t> constants,
276  MLIRContext *context);
277 AffineExpr getAffineBinaryOpExpr(AffineExprKind kind, AffineExpr lhs,
278  AffineExpr rhs);
279 
280 /// Constructs an affine expression from a flat ArrayRef. If there are local
281 /// identifiers (neither dimensional nor symbolic) that appear in the sum of
282 /// products expression, 'localExprs' is expected to have the AffineExpr
283 /// for it, and is substituted into. The ArrayRef 'eq' is expected to be in the
284 /// format [dims, symbols, locals, constant term].
285 AffineExpr getAffineExprFromFlatForm(ArrayRef<int64_t> flatExprs,
286  unsigned numDims, unsigned numSymbols,
287  ArrayRef<AffineExpr> localExprs,
288  MLIRContext *context);
289 
290 raw_ostream &operator<<(raw_ostream &os, AffineExpr expr);
291 
292 template <typename U>
293 constexpr bool AffineExpr::isa() const {
294  if constexpr (std::is_same_v<U, AffineBinaryOpExpr>)
296  if constexpr (std::is_same_v<U, AffineDimExpr>)
297  return getKind() == AffineExprKind::DimId;
298  if constexpr (std::is_same_v<U, AffineSymbolExpr>)
299  return getKind() == AffineExprKind::SymbolId;
300  if constexpr (std::is_same_v<U, AffineConstantExpr>)
301  return getKind() == AffineExprKind::Constant;
302 }
303 template <typename U>
305  return llvm::dyn_cast<U>(*this);
306 }
307 template <typename U>
309  return llvm::dyn_cast_or_null<U>(*this);
310 }
311 template <typename U>
312 U AffineExpr::cast() const {
313  return llvm::cast<U>(*this);
314 }
315 
316 /// Simplify an affine expression by flattening and some amount of simple
317 /// analysis. This has complexity linear in the number of nodes in 'expr'.
318 /// Returns the simplified expression, which is the same as the input expression
319 /// if it can't be simplified. When `expr` is semi-affine, a simplified
320 /// semi-affine expression is constructed in the sorted order of dimension and
321 /// symbol positions.
322 AffineExpr simplifyAffineExpr(AffineExpr expr, unsigned numDims,
323  unsigned numSymbols);
324 
325 namespace detail {
326 template <int N>
327 void bindDims(MLIRContext *ctx) {}
328 
329 template <int N, typename AffineExprTy, typename... AffineExprTy2>
330 void bindDims(MLIRContext *ctx, AffineExprTy &e, AffineExprTy2 &...exprs) {
331  e = getAffineDimExpr(N, ctx);
332  bindDims<N + 1, AffineExprTy2 &...>(ctx, exprs...);
333 }
334 
335 template <int N>
337 
338 template <int N, typename AffineExprTy, typename... AffineExprTy2>
339 void bindSymbols(MLIRContext *ctx, AffineExprTy &e, AffineExprTy2 &...exprs) {
340  e = getAffineSymbolExpr(N, ctx);
341  bindSymbols<N + 1, AffineExprTy2 &...>(ctx, exprs...);
342 }
343 
344 } // namespace detail
345 
346 /// Bind a list of AffineExpr references to DimExpr at positions:
347 /// [0 .. sizeof...(exprs)]
348 template <typename... AffineExprTy>
349 void bindDims(MLIRContext *ctx, AffineExprTy &...exprs) {
350  detail::bindDims<0>(ctx, exprs...);
351 }
352 
353 template <typename AffineExprTy>
355  int idx = 0;
356  for (AffineExprTy &e : exprs)
357  e = getAffineDimExpr(idx++, ctx);
358 }
359 
360 /// Bind a list of AffineExpr references to SymbolExpr at positions:
361 /// [0 .. sizeof...(exprs)]
362 template <typename... AffineExprTy>
363 void bindSymbols(MLIRContext *ctx, AffineExprTy &...exprs) {
364  detail::bindSymbols<0>(ctx, exprs...);
365 }
366 
367 template <typename AffineExprTy>
369  int idx = 0;
370  for (AffineExprTy &e : exprs)
371  e = getAffineSymbolExpr(idx++, ctx);
372 }
373 
374 /// Get a lower or upper (depending on `isUpper`) bound for `expr` while using
375 /// the constant lower and upper bounds for its inputs provided in
376 /// `constLowerBounds` and `constUpperBounds`. Return std::nullopt if such a
377 /// bound can't be computed. This method only handles simple sum of product
378 /// expressions (w.r.t constant coefficients) so as to not depend on anything
379 /// heavyweight in `Analysis`. Expressions of the form: c0*d0 + c1*d1 + c2*s0 +
380 /// ... + c_n are handled. Expressions involving floordiv, ceildiv, mod or
381 /// semi-affine ones will lead a none being returned.
382 std::optional<int64_t>
383 getBoundForAffineExpr(AffineExpr expr, unsigned numDims, unsigned numSymbols,
384  ArrayRef<std::optional<int64_t>> constLowerBounds,
385  ArrayRef<std::optional<int64_t>> constUpperBounds,
386  bool isUpper);
387 
388 } // namespace mlir
389 
390 namespace llvm {
391 
392 // AffineExpr hash just like pointers
393 template <>
394 struct DenseMapInfo<mlir::AffineExpr> {
396  auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
397  return mlir::AffineExpr(static_cast<mlir::AffineExpr::ImplType *>(pointer));
398  }
401  return mlir::AffineExpr(static_cast<mlir::AffineExpr::ImplType *>(pointer));
402  }
403  static unsigned getHashValue(mlir::AffineExpr val) {
404  return mlir::hash_value(val);
405  }
406  static bool isEqual(mlir::AffineExpr LHS, mlir::AffineExpr RHS) {
407  return LHS == RHS;
408  }
409 };
410 
411 /// Add support for llvm style casts. We provide a cast between To and From if
412 /// From is mlir::AffineExpr or derives from it.
413 template <typename To, typename From>
414 struct CastInfo<To, From,
415  std::enable_if_t<std::is_same_v<mlir::AffineExpr,
416  std::remove_const_t<From>> ||
417  std::is_base_of_v<mlir::AffineExpr, From>>>
419  DefaultDoCastIfPossible<To, From, CastInfo<To, From>> {
420 
421  static inline bool isPossible(mlir::AffineExpr expr) {
422  /// Return a constant true instead of a dynamic true when casting to self or
423  /// up the hierarchy.
424  if constexpr (std::is_base_of_v<To, From>) {
425  return true;
426  } else {
427  if constexpr (std::is_same_v<To, ::mlir::AffineBinaryOpExpr>)
428  return expr.getKind() <= ::mlir::AffineExprKind::LAST_AFFINE_BINARY_OP;
429  if constexpr (std::is_same_v<To, ::mlir::AffineDimExpr>)
430  return expr.getKind() == ::mlir::AffineExprKind::DimId;
431  if constexpr (std::is_same_v<To, ::mlir::AffineSymbolExpr>)
432  return expr.getKind() == ::mlir::AffineExprKind::SymbolId;
433  if constexpr (std::is_same_v<To, ::mlir::AffineConstantExpr>)
434  return expr.getKind() == ::mlir::AffineExprKind::Constant;
435  }
436  }
437  static inline To doCast(mlir::AffineExpr expr) { return To(expr.getImpl()); }
438 };
439 
440 } // namespace llvm
441 
442 #endif // MLIR_IR_AFFINEEXPR_H
Affine binary operation expression.
Definition: AffineExpr.h:228
AffineExpr getLHS() const
Definition: AffineExpr.cpp:332
AffineBinaryOpExpr(AffineExpr::ImplType *ptr)
Definition: AffineExpr.cpp:330
AffineExpr getRHS() const
Definition: AffineExpr.cpp:335
An integer constant appearing in affine expression.
Definition: AffineExpr.h:253
AffineConstantExpr(AffineExpr::ImplType *ptr=nullptr)
Definition: AffineExpr.cpp:613
int64_t getValue() const
Definition: AffineExpr.cpp:615
A dimensional identifier appearing in an affine expression.
Definition: AffineExpr.h:237
AffineDimExpr(AffineExpr::ImplType *ptr)
Definition: AffineExpr.cpp:339
unsigned getPosition() const
Definition: AffineExpr.cpp:340
Base type for affine expression.
Definition: AffineExpr.h:69
static AffineExpr getFromOpaquePointer(const void *pointer)
Definition: AffineExpr.h:202
AffineExpr replaceDimsAndSymbols(ArrayRef< AffineExpr > dimReplacements, ArrayRef< AffineExpr > symReplacements) const
This method substitutes any uses of dimensions and symbols (e.g.
Definition: AffineExpr.cpp:81
AffineExpr shiftDims(unsigned numDims, unsigned shift, unsigned offset=0) const
Replace dims[offset ...
Definition: AffineExpr.cpp:125
ImplType * getImpl() const
Definition: AffineExpr.h:207
AffineExpr operator+(int64_t v) const
Definition: AffineExpr.cpp:756
U dyn_cast_or_null() const
Definition: AffineExpr.h:308
friend ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:261
bool isSymbolicOrConstant() const
Returns true if this expression is made out of only symbols and constants, i.e., it does not involve ...
Definition: AffineExpr.cpp:180
AffineExpr operator*(int64_t v) const
Definition: AffineExpr.cpp:817
constexpr AffineExpr()
Definition: AffineExpr.h:73
bool operator==(AffineExpr other) const
Definition: AffineExpr.h:77
bool isPureAffine() const
Returns true if this is a pure affine expression, i.e., multiplication, floordiv, ceildiv,...
Definition: AffineExpr.cpp:204
AffineExpr shiftSymbols(unsigned numSymbols, unsigned shift, unsigned offset=0) const
Replace symbols[offset ...
Definition: AffineExpr.cpp:137
AffineExpr operator-() const
Definition: AffineExpr.cpp:830
U cast() const
Definition: AffineExpr.h:312
AffineExpr floorDiv(uint64_t v) const
Definition: AffineExpr.cpp:883
ImplType * expr
Definition: AffineExpr.h:210
RetT walk(FnT &&callback) const
Walk all of the AffineExpr's in this expression in postorder.
Definition: AffineExpr.h:131
bool operator!=(int64_t v) const
Definition: AffineExpr.h:80
AffineExprKind getKind() const
Return the classification for this type.
Definition: AffineExpr.cpp:27
bool isMultipleOf(int64_t factor) const
Return true if the affine expression is a multiple of 'factor'.
Definition: AffineExpr.cpp:275
bool operator!() const
Definition: AffineExpr.h:83
int64_t getLargestKnownDivisor() const
Returns the greatest known integral divisor of this affine expression.
Definition: AffineExpr.cpp:235
AffineExpr compose(AffineMap map) const
Compose with an AffineMap.
Definition: AffineExpr.cpp:994
constexpr bool isa() const
Definition: AffineExpr.h:293
bool isFunctionOfDim(unsigned position) const
Return true if the affine expression involves AffineDimExpr position.
Definition: AffineExpr.cpp:308
const void * getAsOpaquePointer() const
Methods supporting C API.
Definition: AffineExpr.h:199
bool isFunctionOfSymbol(unsigned position) const
Return true if the affine expression involves AffineSymbolExpr position.
Definition: AffineExpr.cpp:319
AffineExpr replaceDims(ArrayRef< AffineExpr > dimReplacements) const
Dim-only version of replaceDimsAndSymbols.
Definition: AffineExpr.cpp:114
bool operator!=(AffineExpr other) const
Definition: AffineExpr.h:78
AffineExpr operator%(uint64_t v) const
Definition: AffineExpr.cpp:982
MLIRContext * getContext() const
Definition: AffineExpr.cpp:25
AffineExpr replace(AffineExpr expr, AffineExpr replacement) const
Sparse replace method.
Definition: AffineExpr.cpp:173
AffineExpr replaceSymbols(ArrayRef< AffineExpr > symReplacements) const
Symbol-only version of replaceDimsAndSymbols.
Definition: AffineExpr.cpp:119
AffineExpr(const ImplType *expr)
Definition: AffineExpr.h:74
void dump() const
AffineExpr ceilDiv(uint64_t v) const
Definition: AffineExpr.cpp:926
void print(raw_ostream &os) const
U dyn_cast() const
Definition: AffineExpr.h:304
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition: AffineMap.h:47
A symbolic identifier appearing in an affine expression.
Definition: AffineExpr.h:245
AffineSymbolExpr(AffineExpr::ImplType *ptr)
Definition: AffineExpr.cpp:603
unsigned getPosition() const
Definition: AffineExpr.cpp:605
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Include the generated interface declarations.
Definition: CallGraph.h:229
void bindDims(MLIRContext *ctx)
Definition: AffineExpr.h:327
void bindSymbols(MLIRContext *ctx)
Definition: AffineExpr.h:336
Include the generated interface declarations.
std::optional< int64_t > getBoundForAffineExpr(AffineExpr expr, unsigned numDims, unsigned numSymbols, ArrayRef< std::optional< int64_t >> constLowerBounds, ArrayRef< std::optional< int64_t >> constUpperBounds, bool isUpper)
Get a lower or upper (depending on isUpper) bound for expr while using the constant lower and upper b...
void bindDimsList(MLIRContext *ctx, MutableArrayRef< AffineExprTy > exprs)
Definition: AffineExpr.h:354
void bindDims(MLIRContext *ctx, AffineExprTy &...exprs)
Bind a list of AffineExpr references to DimExpr at positions: [0 .
Definition: AffineExpr.h:349
AffineExprKind
Definition: AffineExpr.h:41
@ CeilDiv
RHS of ceildiv is always a constant or a symbolic expression.
@ LAST_AFFINE_BINARY_OP
This is a marker for the last affine binary op.
@ Mul
RHS of mul is always a constant or a symbolic expression.
@ Mod
RHS of mod is always a constant or a symbolic expression with a positive value.
@ DimId
Dimensional identifier.
@ FloorDiv
RHS of floordiv is always a constant or a symbolic expression.
@ Constant
Constant integer.
@ SymbolId
Symbolic identifier.
AffineExpr getAffineBinaryOpExpr(AffineExprKind kind, AffineExpr lhs, AffineExpr rhs)
Definition: AffineExpr.cpp:62
AffineExpr operator-(int64_t val, AffineExpr expr)
Definition: AffineExpr.h:267
AffineExpr getAffineExprFromFlatForm(ArrayRef< int64_t > flatExprs, unsigned numDims, unsigned numSymbols, ArrayRef< AffineExpr > localExprs, MLIRContext *context)
Constructs an affine expression from a flat ArrayRef.
void bindSymbols(MLIRContext *ctx, AffineExprTy &...exprs)
Bind a list of AffineExpr references to SymbolExpr at positions: [0 .
Definition: AffineExpr.h:363
AffineExpr operator+(int64_t val, AffineExpr expr)
Definition: AffineExpr.h:265
AffineExpr operator*(int64_t val, AffineExpr expr)
Definition: AffineExpr.h:266
AffineExpr getAffineConstantExpr(int64_t constant, MLIRContext *context)
Definition: AffineExpr.cpp:623
AffineExpr simplifyAffineExpr(AffineExpr expr, unsigned numDims, unsigned numSymbols)
Simplify an affine expression by flattening and some amount of simple analysis.
SmallVector< AffineExpr > getAffineConstantExprs(ArrayRef< int64_t > constants, MLIRContext *context)
Definition: AffineExpr.cpp:633
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:261
AffineExpr getAffineDimExpr(unsigned position, MLIRContext *context)
These free functions allow clients of the API to not use classes in detail.
Definition: AffineExpr.cpp:599
AffineExpr getAffineSymbolExpr(unsigned position, MLIRContext *context)
Definition: AffineExpr.cpp:609
void bindSymbolsList(MLIRContext *ctx, MutableArrayRef< AffineExprTy > exprs)
Definition: AffineExpr.h:368
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
static unsigned getHashValue(mlir::AffineExpr val)
Definition: AffineExpr.h:403
static mlir::AffineExpr getEmptyKey()
Definition: AffineExpr.h:395
static mlir::AffineExpr getTombstoneKey()
Definition: AffineExpr.h:399
static bool isEqual(mlir::AffineExpr LHS, mlir::AffineExpr RHS)
Definition: AffineExpr.h:406
A binary operation appearing in an affine expression.
An integer constant appearing in affine expression.
A dimensional or symbolic identifier appearing in an affine expression.
Base storage class appearing in an affine expression.