MLIR 22.0.0git
AffineValueMap.cpp
Go to the documentation of this file.
1//===- AffineValueMap.cpp - MLIR Affine Value Map Class -------------------===//
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
11
12using namespace mlir;
13using namespace mlir::affine;
14
16 ValueRange results)
17 : map(map), operands(operands.begin(), operands.end()),
18 results(results.begin(), results.end()) {}
19
21 ValueRange results) {
22 this->map.reset(map);
23 this->operands.assign(operands.begin(), operands.end());
24 this->results.assign(results.begin(), results.end());
25}
26
28 AffineMap sMap = getAffineMap();
29 fullyComposeAffineMapAndOperands(&sMap, &operands);
30 // Full composition also canonicalizes and simplifies before returning. We
31 // need to canonicalize once more to drop unused operands.
32 canonicalizeMapAndOperands(&sMap, &operands);
33 this->map.reset(sMap);
34}
35
37 const AffineValueMap &b, AffineValueMap *res) {
38 assert(a.getNumResults() == b.getNumResults() && "invalid inputs");
39
40 SmallVector<Value, 4> allOperands;
41 allOperands.reserve(a.getNumOperands() + b.getNumOperands());
42 auto aDims = a.getOperands().take_front(a.getNumDims());
43 auto bDims = b.getOperands().take_front(b.getNumDims());
44 auto aSyms = a.getOperands().take_back(a.getNumSymbols());
45 auto bSyms = b.getOperands().take_back(b.getNumSymbols());
46 allOperands.append(aDims.begin(), aDims.end());
47 allOperands.append(bDims.begin(), bDims.end());
48 allOperands.append(aSyms.begin(), aSyms.end());
49 allOperands.append(bSyms.begin(), bSyms.end());
50
51 // Shift dims and symbols of b's map.
52 auto bMap = b.getAffineMap()
53 .shiftDims(a.getNumDims())
54 .shiftSymbols(a.getNumSymbols());
55
56 // Construct the difference expressions.
57 auto aMap = a.getAffineMap();
59 diffExprs.reserve(a.getNumResults());
60 for (unsigned i = 0, e = bMap.getNumResults(); i < e; ++i)
61 diffExprs.push_back(aMap.getResult(i) - bMap.getResult(i));
62
63 auto diffMap = AffineMap::get(bMap.getNumDims(), bMap.getNumSymbols(),
64 diffExprs, bMap.getContext());
65 fullyComposeAffineMapAndOperands(&diffMap, &allOperands);
66 canonicalizeMapAndOperands(&diffMap, &allOperands);
67 diffMap = simplifyAffineMap(diffMap);
68 res->reset(diffMap, allOperands);
69}
70
71// Returns true and sets 'indexOfMatch' if 'valueToMatch' is found in
72// 'valuesToSearch' beginning at 'indexStart'. Returns false otherwise.
73static bool findIndex(Value valueToMatch, ArrayRef<Value> valuesToSearch,
74 unsigned indexStart, unsigned *indexOfMatch) {
75 unsigned size = valuesToSearch.size();
76 for (unsigned i = indexStart; i < size; ++i) {
77 if (valueToMatch == valuesToSearch[i]) {
78 *indexOfMatch = i;
79 return true;
80 }
81 }
82 return false;
83}
84
85bool AffineValueMap::isMultipleOf(unsigned idx, int64_t factor) const {
86 return map.isMultipleOf(idx, factor);
87}
88
89/// This method uses the invariant that operands are always positionally aligned
90/// with the AffineDimExpr in the underlying AffineMap.
91bool AffineValueMap::isFunctionOf(unsigned idx, Value value) const {
92 unsigned index;
93 if (!findIndex(value, operands, /*indexStart=*/0, &index)) {
94 return false;
95 }
96 auto expr = const_cast<AffineValueMap *>(this)->getAffineMap().getResult(idx);
97 // TODO: this is better implemented on a flattened representation.
98 // At least for now it is conservative.
99 return expr.isFunctionOfDim(index);
100}
101
103 return static_cast<Value>(operands[i]);
104}
105
109
110AffineMap AffineValueMap::getAffineMap() const { return map.getAffineMap(); }
111
113 AffineValueMap diff;
114 AffineValueMap::difference(*this, other, &diff);
115 return llvm::all_of(diff.getAffineMap().getResults(), [](AffineExpr e) {
116 return e == getAffineConstantExpr(0, e.getContext());
117 });
118}
119
static bool findIndex(Value valueToMatch, ArrayRef< Value > valuesToSearch, unsigned indexStart, unsigned *indexOfMatch)
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
Base type for affine expression.
Definition AffineExpr.h:68
bool isFunctionOfDim(unsigned position) const
Return true if the affine expression involves AffineDimExpr position.
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Definition AffineMap.h:46
static AffineMap get(MLIRContext *context)
Returns a zero result affine map with no dimensions or symbols: () -> ().
ArrayRef< AffineExpr > getResults() const
AffineExpr getResult(unsigned idx) const
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
Value getOperand(unsigned i) const
bool operator==(const AffineValueMap &other) const
Checks if the application of this map to its operands is semantically equal to other's.
bool isMultipleOf(unsigned idx, int64_t factor) const
Return true if the idx^th result can be proved to be a multiple of 'factor', false otherwise.
void composeSimplifyAndCanonicalize()
Composes all incoming affine.apply ops and then simplifies and canonicalizes the map and operands.
ArrayRef< Value > getOperands() const
unsigned getNumOperands() const
bool isFunctionOf(unsigned idx, Value value) const
Return true if the idx^th result depends on 'value', false otherwise.
void reset(AffineMap map, ValueRange operands, ValueRange results={})
static void difference(const AffineValueMap &a, const AffineValueMap &b, AffineValueMap *res)
Return the value map that is the difference of value maps 'a' and 'b', represented as an affine map a...
void canonicalizeMapAndOperands(AffineMap *map, SmallVectorImpl< Value > *operands)
Modifies both map and operands in-place so as to:
void fullyComposeAffineMapAndOperands(AffineMap *map, SmallVectorImpl< Value > *operands, bool composeAffineMin=false)
Given an affine map map and its input operands, this method composes into map, maps of AffineApplyOps...
Include the generated interface declarations.
AffineMap simplifyAffineMap(AffineMap map)
Simplifies an affine map by simplifying its underlying AffineExpr results.