MLIR  15.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 
15  ValueRange results)
16  : map(map), operands(operands.begin(), operands.end()),
17  results(results.begin(), results.end()) {}
18 
20  ValueRange results) {
21  this->map.reset(map);
22  this->operands.assign(operands.begin(), operands.end());
23  this->results.assign(results.begin(), results.end());
24 }
25 
27  const AffineValueMap &b, AffineValueMap *res) {
28  assert(a.getNumResults() == b.getNumResults() && "invalid inputs");
29 
30  SmallVector<Value, 4> allOperands;
31  allOperands.reserve(a.getNumOperands() + b.getNumOperands());
32  auto aDims = a.getOperands().take_front(a.getNumDims());
33  auto bDims = b.getOperands().take_front(b.getNumDims());
34  auto aSyms = a.getOperands().take_back(a.getNumSymbols());
35  auto bSyms = b.getOperands().take_back(b.getNumSymbols());
36  allOperands.append(aDims.begin(), aDims.end());
37  allOperands.append(bDims.begin(), bDims.end());
38  allOperands.append(aSyms.begin(), aSyms.end());
39  allOperands.append(bSyms.begin(), bSyms.end());
40 
41  // Shift dims and symbols of b's map.
42  auto bMap = b.getAffineMap()
43  .shiftDims(a.getNumDims())
44  .shiftSymbols(a.getNumSymbols());
45 
46  // Construct the difference expressions.
47  auto aMap = a.getAffineMap();
49  diffExprs.reserve(a.getNumResults());
50  for (unsigned i = 0, e = bMap.getNumResults(); i < e; ++i)
51  diffExprs.push_back(aMap.getResult(i) - bMap.getResult(i));
52 
53  auto diffMap = AffineMap::get(bMap.getNumDims(), bMap.getNumSymbols(),
54  diffExprs, bMap.getContext());
55  fullyComposeAffineMapAndOperands(&diffMap, &allOperands);
56  canonicalizeMapAndOperands(&diffMap, &allOperands);
57  diffMap = simplifyAffineMap(diffMap);
58  res->reset(diffMap, allOperands);
59 }
60 
61 // Returns true and sets 'indexOfMatch' if 'valueToMatch' is found in
62 // 'valuesToSearch' beginning at 'indexStart'. Returns false otherwise.
63 static bool findIndex(Value valueToMatch, ArrayRef<Value> valuesToSearch,
64  unsigned indexStart, unsigned *indexOfMatch) {
65  unsigned size = valuesToSearch.size();
66  for (unsigned i = indexStart; i < size; ++i) {
67  if (valueToMatch == valuesToSearch[i]) {
68  *indexOfMatch = i;
69  return true;
70  }
71  }
72  return false;
73 }
74 
75 bool AffineValueMap::isMultipleOf(unsigned idx, int64_t factor) const {
76  return map.isMultipleOf(idx, factor);
77 }
78 
79 /// This method uses the invariant that operands are always positionally aligned
80 /// with the AffineDimExpr in the underlying AffineMap.
81 bool AffineValueMap::isFunctionOf(unsigned idx, Value value) const {
82  unsigned index;
83  if (!findIndex(value, operands, /*indexStart=*/0, &index)) {
84  return false;
85  }
86  auto expr = const_cast<AffineValueMap *>(this)->getAffineMap().getResult(idx);
87  // TODO: this is better implemented on a flattened representation.
88  // At least for now it is conservative.
89  return expr.isFunctionOfDim(index);
90 }
91 
92 Value AffineValueMap::getOperand(unsigned i) const {
93  return static_cast<Value>(operands[i]);
94 }
95 
97  return ArrayRef<Value>(operands);
98 }
99 
101 
Include the generated interface declarations.
bool isFunctionOfDim(unsigned position) const
Return true if the affine expression involves AffineDimExpr position.
Definition: AffineExpr.cpp:280
bool isFunctionOf(unsigned idx, Value value) const
Return true if the idx^th result depends on &#39;value&#39;, false otherwise.
AffineMap shiftDims(unsigned shift, unsigned offset=0) const
Replace dims[offset ...
Definition: AffineMap.h:219
static void difference(const AffineValueMap &a, const AffineValueMap &b, AffineValueMap *res)
Return the value map that is the difference of value maps &#39;a&#39; and &#39;b&#39;, represented as an affine map a...
static constexpr const bool value
AffineExpr getResult(unsigned idx) const
Definition: AffineMap.cpp:311
static AffineMap get(MLIRContext *context)
Returns a zero result affine map with no dimensions or symbols: () -> ().
AffineValueMap()=default
unsigned getNumOperands() const
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:699
void canonicalizeMapAndOperands(AffineMap *map, SmallVectorImpl< Value > *operands)
Modifies both map and operands in-place so as to:
Definition: AffineOps.cpp:873
A multi-dimensional affine map Affine map&#39;s are immutable like Type&#39;s, and they are uniqued...
Definition: AffineMap.h:41
AffineMap getAffineMap() const
unsigned getNumDims() const
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
AffineMap simplifyAffineMap(AffineMap map)
Simplifies an affine map by simplifying its underlying AffineExpr results.
Definition: AffineMap.cpp:639
bool isMultipleOf(unsigned idx, int64_t factor) const
Return true if the idx^th result can be proved to be a multiple of &#39;factor&#39;, false otherwise...
bool isMultipleOf(unsigned idx, int64_t factor) const
Returns true if the idx&#39;th result expression is a multiple of factor.
Definition: AffineMap.cpp:742
AffineMap getAffineMap() const
Get the AffineMap corresponding to this MutableAffineMap.
Definition: AffineMap.cpp:761
unsigned getNumSymbols() const
static bool findIndex(Value valueToMatch, ArrayRef< Value > valuesToSearch, unsigned indexStart, unsigned *indexOfMatch)
An AffineValueMap is an affine map plus its ML value operands and results for analysis purposes...
ArrayRef< Value > getOperands() const
void reset(AffineMap map, ValueRange operands, ValueRange results={})
This class provides an abstraction over the different types of ranges over Values.
Value getOperand(unsigned i) const
unsigned getNumResults() const