MLIR  16.0.0git
AffineMap.h
Go to the documentation of this file.
1 //===- AffineMap.h - MLIR Affine Map 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 // Affine maps are mathematical functions which map a list of dimension
10 // identifiers and symbols, to multidimensional affine expressions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_IR_AFFINEMAP_H
15 #define MLIR_IR_AFFINEMAP_H
16 
17 #include "mlir/IR/AffineExpr.h"
18 #include "mlir/Support/LLVM.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/DenseMapInfo.h"
21 #include "llvm/ADT/SmallBitVector.h"
22 
23 namespace llvm {
24 class SmallBitVector;
25 } // namespace llvm
26 
27 namespace mlir {
28 
29 namespace detail {
30 struct AffineMapStorage;
31 } // namespace detail
32 
33 class Attribute;
34 struct LogicalResult;
35 class MLIRContext;
36 
37 /// A multi-dimensional affine map
38 /// Affine map's are immutable like Type's, and they are uniqued.
39 /// Eg: (d0, d1) -> (d0/128, d0 mod 128, d1)
40 /// The names used (d0, d1) don't matter - it's the mathematical function that
41 /// is unique to this affine map.
42 class AffineMap {
43 public:
45 
46  constexpr AffineMap() = default;
47  explicit AffineMap(ImplType *map) : map(map) {}
48 
49  /// Returns a zero result affine map with no dimensions or symbols: () -> ().
50  static AffineMap get(MLIRContext *context);
51 
52  /// Returns a zero result affine map with `dimCount` dimensions and
53  /// `symbolCount` symbols, e.g.: `(...) -> ()`.
54  static AffineMap get(unsigned dimCount, unsigned symbolCount,
55  MLIRContext *context);
56 
57  /// Returns an affine map with `dimCount` dimensions and `symbolCount` mapping
58  /// to a single output dimension
59  static AffineMap get(unsigned dimCount, unsigned symbolCount,
60  AffineExpr result);
61 
62  /// Returns an affine map with `dimCount` dimensions and `symbolCount` mapping
63  /// to the given results.
64  static AffineMap get(unsigned dimCount, unsigned symbolCount,
65  ArrayRef<AffineExpr> results, MLIRContext *context);
66 
67  /// Returns a single constant result affine map.
68  static AffineMap getConstantMap(int64_t val, MLIRContext *context);
69 
70  /// Returns an AffineMap with 'numDims' identity result dim exprs.
71  static AffineMap getMultiDimIdentityMap(unsigned numDims,
72  MLIRContext *context);
73 
74  /// Returns an identity affine map (d0, ..., dn) -> (dp, ..., dn) on the most
75  /// minor dimensions.
76  static AffineMap getMinorIdentityMap(unsigned dims, unsigned results,
77  MLIRContext *context);
78 
79  /// Returns an AffineMap representing a permutation.
80  /// The permutation is expressed as a non-empty vector of integers.
81  /// E.g. the permutation `(i,j,k) -> (j,k,i)` will be expressed with
82  /// `permutation = [1,2,0]`. All values in `permutation` must be
83  /// integers, in the range 0..`permutation.size()-1` without duplications
84  /// (i.e. `[1,1,2]` is an invalid permutation).
85  static AffineMap getPermutationMap(ArrayRef<unsigned> permutation,
86  MLIRContext *context);
87 
88  /// Returns a vector of AffineMaps; each with as many results as
89  /// `exprs.size()`, as many dims as the largest dim in `exprs` and as many
90  /// symbols as the largest symbol in `exprs`.
95 
96  MLIRContext *getContext() const;
97 
98  explicit operator bool() const { return map != nullptr; }
99  bool operator==(AffineMap other) const { return other.map == map; }
100  bool operator!=(AffineMap other) const { return !(other.map == map); }
101 
102  /// Returns true if this affine map is an identity affine map.
103  /// An identity affine map corresponds to an identity affine function on the
104  /// dimensional identifiers.
105  bool isIdentity() const;
106 
107  /// Returns true if this affine map is a minor identity, i.e. an identity
108  /// affine map (d0, ..., dn) -> (dp, ..., dn) on the most minor dimensions.
109  bool isMinorIdentity() const;
110 
111  /// Returns true if this affine map is a minor identity up to broadcasted
112  /// dimensions which are indicated by value 0 in the result. If
113  /// `broadcastedDims` is not null, it will be populated with the indices of
114  /// the broadcasted dimensions in the result array.
115  /// Example: affine_map<(d0, d1, d2, d3, d4) -> (0, d2, 0, d4)>
116  /// (`broadcastedDims` will contain [0, 2])
117  bool isMinorIdentityWithBroadcasting(
118  SmallVectorImpl<unsigned> *broadcastedDims = nullptr) const;
119 
120  /// Return true if this affine map can be converted to a minor identity with
121  /// broadcast by doing a permute. Return a permutation (there may be
122  /// several) to apply to get to a minor identity with broadcasts.
123  /// Ex:
124  /// * (d0, d1, d2) -> (0, d1) maps to minor identity (d1, 0 = d2) with
125  /// perm = [1, 0] and broadcast d2
126  /// * (d0, d1, d2) -> (d0, 0) cannot be mapped to a minor identity by
127  /// permutation + broadcast
128  /// * (d0, d1, d2, d3) -> (0, d1, d3) maps to minor identity (d1, 0 = d2, d3)
129  /// with perm = [1, 0, 2] and broadcast d2
130  /// * (d0, d1) -> (d1, 0, 0, d0) maps to minor identity (d0, d1) with extra
131  /// leading broadcat dimensions. The map returned would be (0, 0, d0, d1)
132  /// with perm = [3, 0, 1, 2]
133  bool isPermutationOfMinorIdentityWithBroadcasting(
134  SmallVectorImpl<unsigned> &permutedDims) const;
135 
136  /// Returns true if this affine map is an empty map, i.e., () -> ().
137  bool isEmpty() const;
138 
139  /// Returns true if this affine map is a single result constant function.
140  bool isSingleConstant() const;
141 
142  /// Returns true if this affine map has only constant results.
143  bool isConstant() const;
144 
145  /// Returns the constant result of this map. This methods asserts that the map
146  /// has a single constant result.
147  int64_t getSingleConstantResult() const;
148 
149  /// Returns the constant results of this map. This method asserts that the map
150  /// has all constant results.
151  SmallVector<int64_t> getConstantResults() const;
152 
153  // Prints affine map to 'os'.
154  void print(raw_ostream &os) const;
155  void dump() const;
156 
157  unsigned getNumDims() const;
158  unsigned getNumSymbols() const;
159  unsigned getNumResults() const;
160  unsigned getNumInputs() const;
161 
162  ArrayRef<AffineExpr> getResults() const;
163  AffineExpr getResult(unsigned idx) const;
164 
165  /// Extracts the position of the dimensional expression at the given result,
166  /// when the caller knows it is safe to do so.
167  unsigned getDimPosition(unsigned idx) const;
168 
169  /// Extracts the permuted position where given input index resides.
170  /// Fails when called on a non-permutation.
171  unsigned getPermutedPosition(unsigned input) const;
172 
173  /// Return true if any affine expression involves AffineDimExpr `position`.
174  bool isFunctionOfDim(unsigned position) const {
175  return llvm::any_of(getResults(), [&](AffineExpr e) {
176  return e.isFunctionOfDim(position);
177  });
178  }
179 
180  /// Return true if any affine expression involves AffineSymbolExpr `position`.
181  bool isFunctionOfSymbol(unsigned position) const {
182  return llvm::any_of(getResults(), [&](AffineExpr e) {
183  return e.isFunctionOfSymbol(position);
184  });
185  }
186 
187  /// Walk all of the AffineExpr's in this mapping. Each node in an expression
188  /// tree is visited in postorder.
189  void walkExprs(llvm::function_ref<void(AffineExpr)> callback) const;
190 
191  /// This method substitutes any uses of dimensions and symbols (e.g.
192  /// dim#0 with dimReplacements[0]) in subexpressions and returns the modified
193  /// expression mapping. Because this can be used to eliminate dims and
194  /// symbols, the client needs to specify the number of dims and symbols in
195  /// the result. The returned map always has the same number of results.
196  AffineMap replaceDimsAndSymbols(ArrayRef<AffineExpr> dimReplacements,
197  ArrayRef<AffineExpr> symReplacements,
198  unsigned numResultDims,
199  unsigned numResultSyms) const;
200 
201  /// Sparse replace method. Apply AffineExpr::replace(`expr`, `replacement`) to
202  /// each of the results and return a new AffineMap with the new results and
203  /// with the specified number of dims and symbols.
204  AffineMap replace(AffineExpr expr, AffineExpr replacement,
205  unsigned numResultDims, unsigned numResultSyms) const;
206 
207  /// Sparse replace method. Apply AffineExpr::replace(`map`) to each of the
208  /// results and return a new AffineMap with the new results and with inferred
209  /// number of dims and symbols.
210  AffineMap replace(const DenseMap<AffineExpr, AffineExpr> &map) const;
211 
212  /// Sparse replace method. Apply AffineExpr::replace(`map`) to each of the
213  /// results and return a new AffineMap with the new results and with the
214  /// specified number of dims and symbols.
215  AffineMap replace(const DenseMap<AffineExpr, AffineExpr> &map,
216  unsigned numResultDims, unsigned numResultSyms) const;
217 
218  /// Replace dims[offset ... numDims)
219  /// by dims[offset + shift ... shift + numDims).
220  AffineMap shiftDims(unsigned shift, unsigned offset = 0) const {
221  assert(offset <= getNumDims());
222  return AffineMap::get(getNumDims() + shift, getNumSymbols(),
223  llvm::to_vector<4>(llvm::map_range(
224  getResults(),
225  [&](AffineExpr e) {
226  return e.shiftDims(getNumDims(), shift, offset);
227  })),
228  getContext());
229  }
230 
231  /// Replace symbols[offset ... numSymbols)
232  /// by symbols[offset + shift ... shift + numSymbols).
233  AffineMap shiftSymbols(unsigned shift, unsigned offset = 0) const {
234  return AffineMap::get(getNumDims(), getNumSymbols() + shift,
235  llvm::to_vector<4>(llvm::map_range(
236  getResults(),
237  [&](AffineExpr e) {
238  return e.shiftSymbols(getNumSymbols(), shift,
239  offset);
240  })),
241  getContext());
242  }
243 
244  /// Returns a new AffineMap with the same number of dims and symbols and one
245  /// less result at `pos`, dropped.
246  AffineMap dropResult(int64_t pos) {
247  auto exprs = llvm::to_vector<4>(getResults());
248  exprs.erase(exprs.begin() + pos);
249  return AffineMap::get(getNumDims(), getNumSymbols(), exprs, getContext());
250  }
251 
252  // Returns a new AffineMap with the same number of dims and symbols, but all
253  // positions in `positions` dropped from results.
255  AffineMap resultMap = *this;
256  for (int64_t pos : positions)
257  resultMap = resultMap.dropResult(pos);
258  return resultMap;
259  }
260 
261  /// Returns a new AffineMap with the same number of dims and symbols and an
262  /// extra result inserted at `pos`.
263  AffineMap insertResult(AffineExpr expr, unsigned pos) {
264  auto exprs = llvm::to_vector<4>(getResults());
265  exprs.insert(exprs.begin() + pos, expr);
266  return AffineMap::get(getNumDims(), getNumSymbols(), exprs, getContext());
267  }
268 
269  /// Folds the results of the application of an affine map on the provided
270  /// operands to a constant if possible.
271  LogicalResult constantFold(ArrayRef<Attribute> operandConstants,
272  SmallVectorImpl<Attribute> &results) const;
273 
274  /// Propagates the constant operands into this affine map. Operands are
275  /// allowed to be null, at which point they are treated as non-constant. This
276  /// does not change the number of symbols and dimensions. Returns a new map,
277  /// which may be equal to the old map if no folding happened. If `results` is
278  /// provided and if all expressions in the map were folded to constants,
279  /// `results` will contain the values of these constants.
280  AffineMap
281  partialConstantFold(ArrayRef<Attribute> operandConstants,
282  SmallVectorImpl<int64_t> *results = nullptr) const;
283 
284  /// Returns the AffineMap resulting from composing `this` with `map`.
285  /// The resulting AffineMap has as many AffineDimExpr as `map` and as many
286  /// AffineSymbolExpr as the concatenation of `this` and `map` (in which case
287  /// the symbols of `this` map come first).
288  ///
289  /// Prerequisites:
290  /// The maps are composable, i.e. that the number of AffineDimExpr of `this`
291  /// matches the number of results of `map`.
292  ///
293  /// Example:
294  /// map1: `(d0, d1)[s0, s1] -> (d0 + 1 + s1, d1 - 1 - s0)`
295  /// map2: `(d0)[s0] -> (d0 + s0, d0 - s0)`
296  /// map1.compose(map2):
297  /// `(d0)[s0, s1, s2] -> (d0 + s1 + s2 + 1, d0 - s0 - s2 - 1)`
298  AffineMap compose(AffineMap map) const;
299 
300  /// Applies composition by the dims of `this` to the integer `values` and
301  /// returns the resulting values. `this` must be symbol-less.
302  SmallVector<int64_t, 4> compose(ArrayRef<int64_t> values) const;
303 
304  /// Returns true if the AffineMap represents a subset (i.e. a projection) of a
305  /// symbol-less permutation map. `allowZeroInResults` allows projected
306  /// permutation maps with constant zero result expressions.
307  /// TODO: Remove `allowZeroInResults` when constant zero result expressions
308  /// are broadly supported.
309  bool isProjectedPermutation(bool allowZeroInResults = false) const;
310 
311  /// Returns true if the AffineMap represents a symbol-less permutation map.
312  bool isPermutation() const;
313 
314  /// Returns the map consisting of the `resultPos` subset.
315  AffineMap getSubMap(ArrayRef<unsigned> resultPos) const;
316 
317  /// Returns the map consisting of `length` expressions starting from `start`.
318  AffineMap getSliceMap(unsigned start, unsigned length) const;
319 
320  /// Returns the map consisting of the most major `numResults` results.
321  /// Returns the null AffineMap if `numResults` == 0.
322  /// Returns `*this` if `numResults` >= `this->getNumResults()`.
323  AffineMap getMajorSubMap(unsigned numResults) const;
324 
325  /// Returns the map consisting of the most minor `numResults` results.
326  /// Returns the null AffineMap if `numResults` == 0.
327  /// Returns `*this` if `numResults` >= `this->getNumResults()`.
328  AffineMap getMinorSubMap(unsigned numResults) const;
329 
330  /// Get the largest known divisor of all map expressions.
331  /// For eg: for (d0, d1) -> (8*d0 + 4, 4*d1 + 2), the result is 2.
332  /// In the case of maps with no expressions or all zero constant expressions,
333  /// the largest known divisor is trivially the max uint64_t value.
334  uint64_t getLargestKnownDivisorOfMapExprs();
335 
336  friend ::llvm::hash_code hash_value(AffineMap arg);
337 
338  /// Methods supporting C API.
339  const void *getAsOpaquePointer() const {
340  return static_cast<const void *>(map);
341  }
342  static AffineMap getFromOpaquePointer(const void *pointer) {
343  return AffineMap(reinterpret_cast<ImplType *>(const_cast<void *>(pointer)));
344  }
345 
346 private:
347  ImplType *map{nullptr};
348 
349  static AffineMap getImpl(unsigned dimCount, unsigned symbolCount,
350  ArrayRef<AffineExpr> results, MLIRContext *context);
351 };
352 
353 // Make AffineExpr hashable.
354 inline ::llvm::hash_code hash_value(AffineMap arg) {
355  return ::llvm::hash_value(arg.map);
356 }
357 
358 /// A mutable affine map. Its affine expressions are however unique.
360 public:
361  MutableAffineMap() = default;
363 
364  ArrayRef<AffineExpr> getResults() const { return results; }
365  AffineExpr getResult(unsigned idx) const { return results[idx]; }
366  void setResult(unsigned idx, AffineExpr result) { results[idx] = result; }
367  unsigned getNumResults() const { return results.size(); }
368  unsigned getNumDims() const { return numDims; }
369  void setNumDims(unsigned d) { numDims = d; }
370  unsigned getNumSymbols() const { return numSymbols; }
371  void setNumSymbols(unsigned d) { numSymbols = d; }
372  MLIRContext *getContext() const { return context; }
373 
374  /// Returns true if the idx'th result expression is a multiple of factor.
375  bool isMultipleOf(unsigned idx, int64_t factor) const;
376 
377  /// Resets this MutableAffineMap with 'map'.
378  void reset(AffineMap map);
379 
380  /// Simplify the (result) expressions in this map using analysis (used by
381  //-simplify-affine-expr pass).
382  void simplify();
383  /// Get the AffineMap corresponding to this MutableAffineMap. Note that an
384  /// AffineMap will be uniqued and stored in context, while a mutable one
385  /// isn't.
386  AffineMap getAffineMap() const;
387 
388 private:
389  // Same meaning as AffineMap's fields.
391  unsigned numDims = 0;
392  unsigned numSymbols = 0;
393  /// A pointer to the IR's context to store all newly created
394  /// AffineExprStorage's.
395  MLIRContext *context = nullptr;
396 };
397 
398 /// Simplifies an affine map by simplifying its underlying AffineExpr results.
400 
401 /// Drop the dims that are not used.
403 
404 /// Drop the dims that are not used by any of the individual maps in `maps`.
405 /// Asserts that all maps in `maps` are normalized to the same number of
406 /// dims and symbols.
408 
409 /// Drop the dims that are not listed in `unusedDims`.
410 AffineMap compressDims(AffineMap map, const llvm::SmallBitVector &unusedDims);
411 
412 /// Drop the symbols that are not used.
414 
415 /// Drop the symbols that are not used by any of the individual maps in `maps`.
416 /// Asserts that all maps in `maps` are normalized to the same number of
417 /// dims and symbols.
419 
420 /// Drop the symbols that are not listed in `unusedSymbols`.
422  const llvm::SmallBitVector &unusedSymbols);
423 
424 /// Returns a map with the same dimension and symbol count as `map`, but whose
425 /// results are the unique affine expressions of `map`.
427 
428 /// Returns a map of codomain to domain dimensions such that the first codomain
429 /// dimension for a particular domain dimension is selected.
430 /// Returns an empty map if the input map is empty.
431 /// Returns null map (not empty map) if `map` is not invertible (i.e. `map` does
432 /// not contain a subset that is a permutation of full domain rank).
433 ///
434 /// Prerequisites:
435 /// 1. `map` has no symbols.
436 ///
437 /// Example 1:
438 ///
439 /// ```mlir
440 /// (d0, d1, d2) -> (d1, d1, d0, d2, d1, d2, d1, d0)
441 /// 0 2 3
442 /// ```
443 ///
444 /// returns:
445 ///
446 /// ```mlir
447 /// (d0, d1, d2, d3, d4, d5, d6, d7) -> (d2, d0, d3)
448 /// ```
449 ///
450 /// Example 2:
451 ///
452 /// ```mlir
453 /// (d0, d1, d2) -> (d1, d0 + d1, d0, d2, d1, d2, d1, d0)
454 /// 0 2 3
455 /// ```
456 ///
457 /// returns:
458 ///
459 /// ```mlir
460 /// (d0, d1, d2, d3, d4, d5, d6, d7) -> (d2, d0, d3)
461 /// ```
463 
464 /// Return the reverse map of a projected permutation where the projected
465 /// dimensions are transformed into 0s.
466 ///
467 /// Prerequisites: `map` must be a projected permuation.
468 ///
469 /// Example 1:
470 ///
471 /// ```mlir
472 /// affine_map<(d0, d1, d2, d3) -> (d2, d0)>
473 /// ```
474 ///
475 /// returns:
476 ///
477 /// ```mlir
478 /// affine_map<(d0, d1) -> (d1, 0, d0, 0)>
479 /// ```
480 ///
481 /// Example 2:
482 ///
483 /// ```mlir
484 /// affine_map<(d0, d1, d2, d3) -> (d0, d3)>
485 /// ```
486 ///
487 /// returns:
488 ///
489 /// ```mlir
490 /// affine_map<(d0, d1) -> (d0, 0, 0, d1)>
491 /// ```
492 ///
493 /// Example 3:
494 ///
495 /// ```mlir
496 /// affine_map<(d0, d1, d2, d3) -> (d2)>
497 /// ```
498 ///
499 /// returns:
500 ///
501 /// ```mlir
502 /// affine_map<(d0) -> (0, 0, d0, 0)>
503 /// ```
504 /// Example 4:
505 ///
506 /// ```mlir
507 /// affine_map<(d0, d1, d2) -> (d0, 0)>
508 /// ```
509 ///
510 /// returns:
511 ///
512 /// ```mlir
513 /// affine_map<(d0, d1) -> (d0, 0, 0)>
514 /// ```
516 
517 /// Concatenates a list of `maps` into a single AffineMap, stepping over
518 /// potentially empty maps. Assumes each of the underlying map has 0 symbols.
519 /// The resulting map has a number of dims equal to the max of `maps`' dims and
520 /// the concatenated results as its results.
521 /// Returns an empty map if all input `maps` are empty.
522 ///
523 /// Example:
524 /// When applied to the following list of 3 affine maps,
525 ///
526 /// ```mlir
527 /// {
528 /// (i, j, k) -> (i, k),
529 /// (i, j, k) -> (k, j),
530 /// (i, j, k) -> (i, j)
531 /// }
532 /// ```
533 ///
534 /// Returns the map:
535 ///
536 /// ```mlir
537 /// (i, j, k) -> (i, k, k, j, i, j)
538 /// ```
540 
541 /// Returns the map that results from projecting out the dimensions specified in
542 /// `projectedDimensions`. The projected dimensions are set to 0.
543 ///
544 /// Example:
545 /// 1) map : affine_map<(d0, d1, d2) -> (d0, d1)>
546 /// projected_dimensions : {2}
547 /// result : affine_map<(d0, d1) -> (d0, d1)>
548 ///
549 /// 2) map : affine_map<(d0, d1) -> (d0 + d1)>
550 /// projected_dimensions : {1}
551 /// result : affine_map<(d0) -> (d0)>
552 ///
553 /// 3) map : affine_map<(d0, d1, d2) -> (d0, d1)>
554 /// projected_dimensions : {1}
555 /// result : affine_map<(d0, d1) -> (d0, 0)>
556 ///
557 /// This function also compresses unused symbols away.
559  const llvm::SmallBitVector &projectedDimensions);
560 
561 /// Apply a permutation from `map` to `source` and return the result.
562 template <typename T>
564  assert(map.isProjectedPermutation());
565  assert(map.getNumInputs() == source.size());
566  SmallVector<T> result;
567  result.reserve(map.getNumResults());
568  for (AffineExpr expr : map.getResults()) {
569  if (auto dimExpr = expr.dyn_cast<AffineDimExpr>()) {
570  result.push_back(source[dimExpr.getPosition()]);
571  } else if (auto constExpr = expr.dyn_cast<AffineConstantExpr>()) {
572  assert(constExpr.getValue() == 0 &&
573  "Unexpected constant in projected permutation map");
574  result.push_back(0);
575  } else {
576  llvm_unreachable("Unexpected result in projected permutation map");
577  }
578  }
579  return result;
580 }
581 
582 /// Calculates maxmimum dimension and symbol positions from the expressions
583 /// in `exprsLists` and stores them in `maxDim` and `maxSym` respectively.
584 template <typename AffineExprContainer>
586  int64_t &maxDim, int64_t &maxSym) {
587  for (const auto &exprs : exprsList) {
588  for (auto expr : exprs) {
589  expr.walk([&maxDim, &maxSym](AffineExpr e) {
590  if (auto d = e.dyn_cast<AffineDimExpr>())
591  maxDim = std::max(maxDim, static_cast<int64_t>(d.getPosition()));
592  if (auto s = e.dyn_cast<AffineSymbolExpr>())
593  maxSym = std::max(maxSym, static_cast<int64_t>(s.getPosition()));
594  });
595  }
596  }
597 }
598 
599 inline raw_ostream &operator<<(raw_ostream &os, AffineMap map) {
600  map.print(os);
601  return os;
602 }
603 
604 // Return a bitvector where each bit set indicates a dimension that is not used
605 // by any of the maps in the input array `maps`.
606 llvm::SmallBitVector getUnusedDimsBitVector(ArrayRef<AffineMap> maps);
607 
608 } // namespace mlir
609 
610 namespace llvm {
611 
612 // AffineExpr hash just like pointers
613 template <>
614 struct DenseMapInfo<mlir::AffineMap> {
616  auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
617  return mlir::AffineMap(static_cast<mlir::AffineMap::ImplType *>(pointer));
618  }
621  return mlir::AffineMap(static_cast<mlir::AffineMap::ImplType *>(pointer));
622  }
623  static unsigned getHashValue(mlir::AffineMap val) {
624  return mlir::hash_value(val);
625  }
626  static bool isEqual(mlir::AffineMap LHS, mlir::AffineMap RHS) {
627  return LHS == RHS;
628  }
629 };
630 
631 } // namespace llvm
632 
633 #endif // MLIR_IR_AFFINEMAP_H
Include the generated interface declarations.
AffineMap inversePermutation(AffineMap map)
Returns a map of codomain to domain dimensions such that the first codomain dimension for a particula...
Definition: AffineMap.cpp:665
static bool isEqual(mlir::AffineMap LHS, mlir::AffineMap RHS)
Definition: AffineMap.h:626
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
static void getMaxDimAndSymbol(ArrayRef< AffineExprContainer > exprsList, int64_t &maxDim, int64_t &maxSym)
Calculates maxmimum dimension and symbol positions from the expressions in exprsLists and stores them...
Definition: AffineMap.h:585
bool isFunctionOfDim(unsigned position) const
Return true if the affine expression involves AffineDimExpr position.
Definition: AffineExpr.cpp:279
AffineExpr shiftSymbols(unsigned numSymbols, unsigned shift, unsigned offset=0) const
Replace symbols[offset ...
Definition: AffineExpr.cpp:121
AffineExpr shiftDims(unsigned numDims, unsigned shift, unsigned offset=0) const
Replace dims[offset ...
Definition: AffineExpr.cpp:109
unsigned getNumResults() const
Definition: AffineMap.h:367
AffineMap shiftSymbols(unsigned shift, unsigned offset=0) const
Replace symbols[offset ...
Definition: AffineMap.h:233
void setNumDims(unsigned d)
Definition: AffineMap.h:369
bool operator!=(AffineMap other) const
Definition: AffineMap.h:100
AffineMap shiftDims(unsigned shift, unsigned offset=0) const
Replace dims[offset ...
Definition: AffineMap.h:220
bool isFunctionOfSymbol(unsigned position) const
Return true if any affine expression involves AffineSymbolExpr position.
Definition: AffineMap.h:181
An integer constant appearing in affine expression.
Definition: AffineExpr.h:232
AffineMap compressSymbols(AffineMap map, const llvm::SmallBitVector &unusedSymbols)
Drop the symbols that are not listed in unusedSymbols.
Definition: AffineMap.cpp:613
unsigned getNumInputs() const
Definition: AffineMap.cpp:315
static mlir::AffineMap getEmptyKey()
Definition: AffineMap.h:615
U dyn_cast() const
Definition: AffineExpr.h:281
AffineMap dropResults(ArrayRef< int64_t > positions)
Definition: AffineMap.h:254
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
AffineMap removeDuplicateExprs(AffineMap map)
Returns a map with the same dimension and symbol count as map, but whose results are the unique affin...
Definition: AffineMap.cpp:656
bool operator==(AffineMap other) const
Definition: AffineMap.h:99
llvm::SmallBitVector getUnusedDimsBitVector(ArrayRef< AffineMap > maps)
Definition: AffineMap.cpp:732
A mutable affine map. Its affine expressions are however unique.
Definition: AffineMap.h:359
SmallVector< T > applyPermutationMap(AffineMap map, llvm::ArrayRef< T > source)
Apply a permutation from map to source and return the result.
Definition: AffineMap.h:563
bool isProjectedPermutation(bool allowZeroInResults=false) const
Returns true if the AffineMap represents a subset (i.e.
Definition: AffineMap.cpp:490
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
AffineMap concatAffineMaps(ArrayRef< AffineMap > maps)
Concatenates a list of maps into a single AffineMap, stepping over potentially empty maps...
Definition: AffineMap.cpp:710
inline ::llvm::hash_code hash_value(AffineMap arg)
Definition: AffineMap.h:354
unsigned getNumSymbols() const
Definition: AffineMap.h:370
Base type for affine expression.
Definition: AffineExpr.h:68
static mlir::AffineMap getTombstoneKey()
Definition: AffineMap.h:619
unsigned getNumResults() const
Definition: AffineMap.cpp:314
A multi-dimensional affine map Affine map&#39;s are immutable like Type&#39;s, and they are uniqued...
Definition: AffineMap.h:42
ArrayRef< AffineExpr > getResults() const
Definition: AffineMap.cpp:319
bool isFunctionOfSymbol(unsigned position) const
Return true if the affine expression involves AffineSymbolExpr position.
Definition: AffineExpr.cpp:290
AffineMap inverseAndBroadcastProjectedPermutation(AffineMap map)
Return the reverse map of a projected permutation where the projected dimensions are transformed into...
Definition: AffineMap.cpp:689
static unsigned getHashValue(mlir::AffineMap val)
Definition: AffineMap.h:623
MLIRContext * getContext() const
Definition: AffineMap.h:372
bool isPermutation(ArrayRef< int64_t > permutation)
Check if permutation is a permutation of the range [0, permutation.size()).
Definition: Utils.cpp:189
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:240
const void * getAsOpaquePointer() const
Methods supporting C API.
Definition: AffineMap.h:339
void print(raw_ostream &os) const
AffineExpr getResult(unsigned idx) const
Definition: AffineMap.h:365
AffineMap dropResult(int64_t pos)
Returns a new AffineMap with the same number of dims and symbols and one less result at pos...
Definition: AffineMap.h:246
void setResult(unsigned idx, AffineExpr result)
Definition: AffineMap.h:366
void setNumSymbols(unsigned d)
Definition: AffineMap.h:371
unsigned getNumDims() const
Definition: AffineMap.h:368
AffineMap simplifyAffineMap(AffineMap map)
Simplifies an affine map by simplifying its underlying AffineExpr results.
Definition: AffineMap.cpp:646
ArrayRef< AffineExpr > getResults() const
Definition: AffineMap.h:364
AffineMap compressDims(AffineMap map, const llvm::SmallBitVector &unusedDims)
Drop the dims that are not listed in unusedDims.
Definition: AffineMap.cpp:555
AffineMap getProjectedMap(AffineMap map, const llvm::SmallBitVector &projectedDimensions)
Returns the map that results from projecting out the dimensions specified in projectedDimensions.
Definition: AffineMap.cpp:727
A dimensional identifier appearing in an affine expression.
Definition: AffineExpr.h:216
AffineMap insertResult(AffineExpr expr, unsigned pos)
Returns a new AffineMap with the same number of dims and symbols and an extra result inserted at pos...
Definition: AffineMap.h:263
bool isFunctionOfDim(unsigned position) const
Return true if any affine expression involves AffineDimExpr position.
Definition: AffineMap.h:174
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:56
SmallVector< AffineMap > compressUnusedSymbols(ArrayRef< AffineMap > maps)
Drop the symbols that are not used by any of the individual maps in maps.
Definition: AffineMap.cpp:641
raw_ostream & operator<<(raw_ostream &os, AffineMap map)
Definition: AffineMap.h:599
static AffineMap getFromOpaquePointer(const void *pointer)
Definition: AffineMap.h:342
AffineMap(ImplType *map)
Definition: AffineMap.h:47
SmallVector< AffineMap > compressUnusedDims(ArrayRef< AffineMap > maps)
Drop the dims that are not used by any of the individual maps in maps.
Definition: AffineMap.cpp:608
static llvm::Optional< unsigned > getDimPosition(AffineMap map, unsigned dim)
Look for a given dimension in an affine map and return its position.
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
A symbolic identifier appearing in an affine expression.
Definition: AffineExpr.h:224
static SmallVector< AffineMap, 4 > inferFromExprList(ArrayRef< AffineExprContainer > exprsList)
Definition: AffineMap.cpp:221