File: AffineValueMap.cpp

package info (click to toggle)
swiftlang 6.1.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,791,604 kB
  • sloc: cpp: 9,901,740; ansic: 2,201,431; asm: 1,091,827; python: 308,252; objc: 82,166; f90: 80,126; lisp: 38,358; pascal: 25,559; sh: 20,429; ml: 5,058; perl: 4,745; makefile: 4,484; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (112 lines) | stat: -rw-r--r-- 4,356 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//===- AffineValueMap.cpp - MLIR Affine Value Map Class -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/Affine/IR/AffineValueMap.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"

using namespace mlir;
using namespace mlir::affine;

AffineValueMap::AffineValueMap(AffineMap map, ValueRange operands,
                               ValueRange results)
    : map(map), operands(operands.begin(), operands.end()),
      results(results.begin(), results.end()) {}

void AffineValueMap::reset(AffineMap map, ValueRange operands,
                           ValueRange results) {
  this->map.reset(map);
  this->operands.assign(operands.begin(), operands.end());
  this->results.assign(results.begin(), results.end());
}

void AffineValueMap::composeSimplifyAndCanonicalize() {
  AffineMap sMap = getAffineMap();
  fullyComposeAffineMapAndOperands(&sMap, &operands);
  // Full composition also canonicalizes and simplifies before returning. We
  // need to canonicalize once more to drop unused operands.
  canonicalizeMapAndOperands(&sMap, &operands);
  this->map.reset(sMap);
}

void AffineValueMap::difference(const AffineValueMap &a,
                                const AffineValueMap &b, AffineValueMap *res) {
  assert(a.getNumResults() == b.getNumResults() && "invalid inputs");

  SmallVector<Value, 4> allOperands;
  allOperands.reserve(a.getNumOperands() + b.getNumOperands());
  auto aDims = a.getOperands().take_front(a.getNumDims());
  auto bDims = b.getOperands().take_front(b.getNumDims());
  auto aSyms = a.getOperands().take_back(a.getNumSymbols());
  auto bSyms = b.getOperands().take_back(b.getNumSymbols());
  allOperands.append(aDims.begin(), aDims.end());
  allOperands.append(bDims.begin(), bDims.end());
  allOperands.append(aSyms.begin(), aSyms.end());
  allOperands.append(bSyms.begin(), bSyms.end());

  // Shift dims and symbols of b's map.
  auto bMap = b.getAffineMap()
                  .shiftDims(a.getNumDims())
                  .shiftSymbols(a.getNumSymbols());

  // Construct the difference expressions.
  auto aMap = a.getAffineMap();
  SmallVector<AffineExpr, 4> diffExprs;
  diffExprs.reserve(a.getNumResults());
  for (unsigned i = 0, e = bMap.getNumResults(); i < e; ++i)
    diffExprs.push_back(aMap.getResult(i) - bMap.getResult(i));

  auto diffMap = AffineMap::get(bMap.getNumDims(), bMap.getNumSymbols(),
                                diffExprs, bMap.getContext());
  fullyComposeAffineMapAndOperands(&diffMap, &allOperands);
  canonicalizeMapAndOperands(&diffMap, &allOperands);
  diffMap = simplifyAffineMap(diffMap);
  res->reset(diffMap, allOperands);
}

// Returns true and sets 'indexOfMatch' if 'valueToMatch' is found in
// 'valuesToSearch' beginning at 'indexStart'. Returns false otherwise.
static bool findIndex(Value valueToMatch, ArrayRef<Value> valuesToSearch,
                      unsigned indexStart, unsigned *indexOfMatch) {
  unsigned size = valuesToSearch.size();
  for (unsigned i = indexStart; i < size; ++i) {
    if (valueToMatch == valuesToSearch[i]) {
      *indexOfMatch = i;
      return true;
    }
  }
  return false;
}

bool AffineValueMap::isMultipleOf(unsigned idx, int64_t factor) const {
  return map.isMultipleOf(idx, factor);
}

/// This method uses the invariant that operands are always positionally aligned
/// with the AffineDimExpr in the underlying AffineMap.
bool AffineValueMap::isFunctionOf(unsigned idx, Value value) const {
  unsigned index;
  if (!findIndex(value, operands, /*indexStart=*/0, &index)) {
    return false;
  }
  auto expr = const_cast<AffineValueMap *>(this)->getAffineMap().getResult(idx);
  // TODO: this is better implemented on a flattened representation.
  // At least for now it is conservative.
  return expr.isFunctionOfDim(index);
}

Value AffineValueMap::getOperand(unsigned i) const {
  return static_cast<Value>(operands[i]);
}

ArrayRef<Value> AffineValueMap::getOperands() const {
  return ArrayRef<Value>(operands);
}

AffineMap AffineValueMap::getAffineMap() const { return map.getAffineMap(); }

AffineValueMap::~AffineValueMap() = default;