My Project
AffineExpr.h
Go to the documentation of this file.
1 //===- AffineExpr.h - MLIR Affine Expr Class --------------------*- C++ -*-===//
2 //
3 // Part of the MLIR 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_AFFINE_EXPR_H
15 #define MLIR_IR_AFFINE_EXPR_H
16 
17 #include "mlir/Support/LLVM.h"
18 #include "llvm/ADT/DenseMapInfo.h"
19 #include "llvm/Support/Casting.h"
20 #include <type_traits>
21 
22 namespace mlir {
23 
24 class MLIRContext;
25 class AffineMap;
26 class IntegerSet;
27 
28 namespace detail {
29 
30 struct AffineExprStorage;
31 struct AffineBinaryOpExprStorage;
32 struct AffineDimExprStorage;
33 struct AffineSymbolExprStorage;
34 struct AffineConstantExprStorage;
35 
36 } // namespace detail
37 
38 enum class AffineExprKind {
39  Add,
41  Mul,
44  Mod,
46  FloorDiv,
48  CeilDiv,
49 
52  LAST_AFFINE_BINARY_OP = CeilDiv,
53 
55  Constant,
57  DimId,
59  SymbolId,
60 };
61 
66 class AffineExpr {
67 public:
69 
70  AffineExpr() : expr(nullptr) {}
71  /* implicit */ AffineExpr(const ImplType *expr)
72  : expr(const_cast<ImplType *>(expr)) {}
73 
74  AffineExpr(const AffineExpr &other) : expr(other.expr) {}
76  expr = other.expr;
77  return *this;
78  }
79 
80  bool operator==(AffineExpr other) const { return expr == other.expr; }
81  bool operator!=(AffineExpr other) const { return !(*this == other); }
82  bool operator==(int64_t v) const;
83  bool operator!=(int64_t v) const { return !(*this == v); }
84  explicit operator bool() const { return expr; }
85 
86  bool operator!() const { return expr == nullptr; }
87 
88  template <typename U> bool isa() const;
89  template <typename U> U dyn_cast() const;
90  template <typename U> U dyn_cast_or_null() const;
91  template <typename U> U cast() const;
92 
93  MLIRContext *getContext() const;
94 
96  AffineExprKind getKind() const;
97 
98  void print(raw_ostream &os) const;
99  void dump() const;
100 
103  bool isSymbolicOrConstant() const;
104 
107  bool isPureAffine() const;
108 
111  int64_t getLargestKnownDivisor() const;
112 
114  bool isMultipleOf(int64_t factor) const;
115 
117  bool isFunctionOfDim(unsigned position) const;
118 
120  void walk(std::function<void(AffineExpr)> callback) const;
121 
124  AffineExpr replaceDimsAndSymbols(ArrayRef<AffineExpr> dimReplacements,
125  ArrayRef<AffineExpr> symReplacements) const;
126 
127  AffineExpr operator+(int64_t v) const;
128  AffineExpr operator+(AffineExpr other) const;
129  AffineExpr operator-() const;
130  AffineExpr operator-(int64_t v) const;
131  AffineExpr operator-(AffineExpr other) const;
132  AffineExpr operator*(int64_t v) const;
133  AffineExpr operator*(AffineExpr other) const;
134  AffineExpr floorDiv(uint64_t v) const;
135  AffineExpr floorDiv(AffineExpr other) const;
136  AffineExpr ceilDiv(uint64_t v) const;
137  AffineExpr ceilDiv(AffineExpr other) const;
138  AffineExpr operator%(uint64_t v) const;
139  AffineExpr operator%(AffineExpr other) const;
140 
154  AffineExpr compose(AffineMap map) const;
155 
156  friend ::llvm::hash_code hash_value(AffineExpr arg);
157 
158 protected:
160 };
161 
169 public:
171  /* implicit */ AffineBinaryOpExpr(AffineExpr::ImplType *ptr);
172  AffineExpr getLHS() const;
173  AffineExpr getRHS() const;
174 };
175 
177 class AffineDimExpr : public AffineExpr {
178 public:
180  /* implicit */ AffineDimExpr(AffineExpr::ImplType *ptr);
181  unsigned getPosition() const;
182 };
183 
185 class AffineSymbolExpr : public AffineExpr {
186 public:
188  /* implicit */ AffineSymbolExpr(AffineExpr::ImplType *ptr);
189  unsigned getPosition() const;
190 };
191 
194 public:
196  /* implicit */ AffineConstantExpr(AffineExpr::ImplType *ptr);
197  int64_t getValue() const;
198 };
199 
201 inline ::llvm::hash_code hash_value(AffineExpr arg) {
203 }
204 
205 inline AffineExpr operator+(int64_t val, AffineExpr expr) { return expr + val; }
206 inline AffineExpr operator*(int64_t val, AffineExpr expr) { return expr * val; }
207 inline AffineExpr operator-(int64_t val, AffineExpr expr) {
208  return expr * (-1) + val;
209 }
210 
212 AffineExpr getAffineDimExpr(unsigned position, MLIRContext *context);
213 AffineExpr getAffineSymbolExpr(unsigned position, MLIRContext *context);
216  AffineExpr rhs);
217 
223 AffineExpr toAffineExpr(ArrayRef<int64_t> eq, unsigned numDims,
224  unsigned numSymbols, ArrayRef<AffineExpr> localExprs,
225  MLIRContext *context);
226 
227 raw_ostream &operator<<(raw_ostream &os, AffineExpr &expr);
228 
229 template <typename U> bool AffineExpr::isa() const {
230  if (std::is_same<U, AffineBinaryOpExpr>::value)
231  return getKind() <= AffineExprKind::LAST_AFFINE_BINARY_OP;
232  if (std::is_same<U, AffineDimExpr>::value)
233  return getKind() == AffineExprKind::DimId;
234  if (std::is_same<U, AffineSymbolExpr>::value)
235  return getKind() == AffineExprKind::SymbolId;
236  if (std::is_same<U, AffineConstantExpr>::value)
237  return getKind() == AffineExprKind::Constant;
238 }
239 template <typename U> U AffineExpr::dyn_cast() const {
240  if (isa<U>())
241  return U(expr);
242  return U(nullptr);
243 }
244 template <typename U> U AffineExpr::dyn_cast_or_null() const {
245  return (!*this || !isa<U>()) ? U(nullptr) : U(expr);
246 }
247 template <typename U> U AffineExpr::cast() const {
248  assert(isa<U>());
249  return U(expr);
250 }
251 
256 AffineExpr simplifyAffineExpr(AffineExpr expr, unsigned numDims,
257  unsigned numSymbols);
258 
263 bool getFlattenedAffineExpr(AffineExpr expr, unsigned numDims,
264  unsigned numSymbols,
265  SmallVectorImpl<int64_t> *flattenedExpr);
266 
275  AffineMap map, std::vector<SmallVector<int64_t, 8>> *flattenedExprs);
277  IntegerSet set, std::vector<SmallVector<int64_t, 8>> *flattenedExprs);
278 
279 namespace detail {
280 template <int N> void bindDims(MLIRContext *ctx) {}
281 
282 template <int N, typename AffineExprTy, typename... AffineExprTy2>
283 void bindDims(MLIRContext *ctx, AffineExprTy &e, AffineExprTy2 &... exprs) {
284  e = getAffineDimExpr(N, ctx);
285  bindDims<N + 1, AffineExprTy2 &...>(ctx, exprs...);
286 }
287 } // namespace detail
288 
291 template <typename... AffineExprTy>
292 void bindDims(MLIRContext *ctx, AffineExprTy &... exprs) {
293  detail::bindDims<0>(ctx, exprs...);
294 }
295 
296 } // namespace mlir
297 
298 namespace llvm {
299 
300 // AffineExpr hash just like pointers
301 template <> struct DenseMapInfo<mlir::AffineExpr> {
304  return mlir::AffineExpr(static_cast<mlir::AffineExpr::ImplType *>(pointer));
305  }
308  return mlir::AffineExpr(static_cast<mlir::AffineExpr::ImplType *>(pointer));
309  }
310  static unsigned getHashValue(mlir::AffineExpr val) {
311  return mlir::hash_value(val);
312  }
313  static bool isEqual(mlir::AffineExpr LHS, mlir::AffineExpr RHS) {
314  return LHS == RHS;
315  }
316 };
317 
318 } // namespace llvm
319 
320 #endif // MLIR_IR_AFFINE_EXPR_H
Definition: AffineExpr.h:168
Definition: InferTypeOpInterface.cpp:20
AffineExpr & operator=(AffineExpr other)
Definition: AffineExpr.h:75
LogicalResult getFlattenedAffineExprs(AffineMap map, std::vector< SmallVector< int64_t, 8 >> *flattenedExprs, FlatAffineConstraints *cst=nullptr)
Definition: AffineStructures.cpp:115
Base storage class appearing in an affine expression.
Definition: AffineExprDetail.h:28
void bindDims(MLIRContext *ctx)
Definition: AffineExpr.h:280
Definition: PassRegistry.cpp:413
AffineExpr getAffineConstantExpr(int64_t constant, MLIRContext *context)
Definition: AffineExpr.cpp:277
ValueHandle operator%(ValueHandle lhs, ValueHandle rhs)
Definition: Builders.cpp:390
Definition: Attributes.h:129
Definition: LLVM.h:45
static mlir::AffineExpr getEmptyKey()
Definition: AffineExpr.h:302
bool operator==(AffineExpr other) const
Definition: AffineExpr.h:80
IntInfty operator+(IntInfty lhs, IntInfty rhs)
Definition: SDBM.h:57
A binary operation appearing in an affine expression.
Definition: AffineExprDetail.h:33
ImplType * expr
Definition: AffineExpr.h:159
Definition: Parser.cpp:2392
An integer constant appearing in affine expression.
Definition: AffineExpr.h:193
Definition: LLVM.h:34
AffineExpr simplifyAffineExpr(AffineExpr expr, unsigned numDims, unsigned numSymbols)
Simplify the affine expression by flattening it and reconstructing it.
Definition: AffineExpr.cpp:839
U dyn_cast() const
Definition: AffineExpr.h:239
Definition: LLVM.h:37
int64_t floorDiv(int64_t lhs, int64_t rhs)
Definition: MathExtras.h:31
static bool isEqual(mlir::AffineExpr LHS, mlir::AffineExpr RHS)
Definition: AffineExpr.h:313
AffineExpr(const ImplType *expr)
Definition: AffineExpr.h:71
LogicalResult getFlattenedAffineExpr(AffineExpr expr, unsigned numDims, unsigned numSymbols, SmallVectorImpl< int64_t > *flattenedExpr, FlatAffineConstraints *cst=nullptr)
Definition: AffineStructures.cpp:102
AffineExpr getAffineSymbolExpr(unsigned position, MLIRContext *context)
Definition: AffineExpr.cpp:262
int64_t ceilDiv(int64_t lhs, int64_t rhs)
Definition: MathExtras.h:23
auto map(Fn fun, IterType begin, IterType end) -> SmallVector< typename std::result_of< Fn(decltype(*begin))>::type, 8 >
Map with iterators.
Definition: Functional.h:28
Definition: AffineExpr.h:66
Definition: Parser.cpp:2393
Definition: AffineMap.h:37
U cast() const
Definition: AffineExpr.h:247
ValueBuilder< mlir::LLVM::ConstantOp > constant
Definition: LinalgToLLVM.cpp:56
U dyn_cast_or_null() const
Definition: AffineExpr.h:244
AffineExpr getAffineDimExpr(unsigned position, MLIRContext *context)
These free functions allow clients of the API to not use classes in detail.
Definition: AffineExpr.cpp:252
AffineExpr getAffineBinaryOpExpr(AffineExprKind kind, AffineExpr lhs, AffineExpr rhs)
Definition: AffineExpr.cpp:45
static unsigned getHashValue(mlir::AffineExpr val)
Definition: AffineExpr.h:310
bool operator==(IntInfty lhs, IntInfty rhs)
Definition: SDBM.h:90
bool isa() const
Definition: AffineExpr.h:229
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:201
bool operator!=(int64_t v) const
Definition: AffineExpr.h:83
Definition: LLVM.h:35
A dimensional or symbolic identifier appearing in an affine expression.
Definition: AffineExprDetail.h:54
AffineExpr()
Definition: AffineExpr.h:70
A dimensional identifier appearing in an affine expression.
Definition: AffineExpr.h:177
AffineExpr(const AffineExpr &other)
Definition: AffineExpr.h:74
AffineExprKind
Definition: AffineExpr.h:38
Definition: Parser.cpp:2381
Definition: MLIRContext.h:34
void print(OpAsmPrinter &p, AffineIfOp op)
Definition: AffineOps.cpp:1671
AffineExpr operator-(int64_t val, AffineExpr expr)
Definition: AffineExpr.h:207
An integer constant appearing in affine expression.
Definition: AffineExprDetail.h:71
Definition: Parser.cpp:2391
AffineExpr toAffineExpr(ArrayRef< int64_t > eq, unsigned numDims, unsigned numSymbols, ArrayRef< AffineExpr > localExprs, MLIRContext *context)
Definition: AffineExpr.cpp:594
raw_ostream & operator<<(raw_ostream &os, SubViewOp::Range &range)
Definition: Ops.cpp:2759
AffineExpr operator*(int64_t val, AffineExpr expr)
Definition: AffineExpr.h:206
Definition: Parser.cpp:2390
static mlir::AffineExpr getTombstoneKey()
Definition: AffineExpr.h:306
bool operator!=(AffineExpr other) const
Definition: AffineExpr.h:81
Definition: Attributes.h:135
bool operator!() const
Definition: AffineExpr.h:86
A symbolic identifier appearing in an affine expression.
Definition: AffineExpr.h:185
Definition: IntegerSet.h:42