MLIR  20.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 
12 using namespace mlir;
13 using 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())
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.
73 static 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 
85 bool 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.
91 bool 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 
107  return ArrayRef<Value>(operands);
108 }
109 
111 
static bool findIndex(Value valueToMatch, ArrayRef< Value > valuesToSearch, unsigned indexStart, unsigned *indexOfMatch)
bool isFunctionOfDim(unsigned position) const
Return true if the affine expression involves AffineDimExpr position.
Definition: AffineExpr.cpp:316
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: () -> ().
AffineMap shiftDims(unsigned shift, unsigned offset=0) const
Replace dims[offset ...
Definition: AffineMap.h:267
AffineMap shiftSymbols(unsigned shift, unsigned offset=0) const
Replace symbols[offset ...
Definition: AffineMap.h:280
AffineExpr getResult(unsigned idx) const
Definition: AffineMap.cpp:411
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:381
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
An AffineValueMap is an affine map plus its ML value operands and results for analysis purposes.
Value getOperand(unsigned i) const
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.
unsigned getNumSymbols() const
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={})
unsigned getNumResults() const
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 fullyComposeAffineMapAndOperands(AffineMap *map, SmallVectorImpl< Value > *operands)
Given an affine map map and its input operands, this method composes into map, maps of AffineApplyOps...
Definition: AffineOps.cpp:1134
void canonicalizeMapAndOperands(AffineMap *map, SmallVectorImpl< Value > *operands)
Modifies both map and operands in-place so as to:
Definition: AffineOps.cpp:1435
Include the generated interface declarations.
AffineMap simplifyAffineMap(AffineMap map)
Simplifies an affine map by simplifying its underlying AffineExpr results.
Definition: AffineMap.cpp:773
void reset(AffineMap map)
Resets this MutableAffineMap with 'map'.
Definition: AffineMap.cpp:968
AffineMap getAffineMap() const
Get the AffineMap corresponding to this MutableAffineMap.
Definition: AffineMap.cpp:990
bool isMultipleOf(unsigned idx, int64_t factor) const
Returns true if the idx'th result expression is a multiple of factor.
Definition: AffineMap.cpp:976