Coverage Report

Created: 2020-06-26 05:44

/home/arjun/llvm-project/mlir/lib/Dialect/Affine/IR/AffineValueMap.cpp
Line
Count
Source (jump to first uncovered line)
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
9
#include "mlir/Dialect/Affine/IR/AffineValueMap.h"
10
#include "mlir/Dialect/Affine/IR/AffineOps.h"
11
12
using namespace mlir;
13
14
AffineValueMap::AffineValueMap(AffineMap map, ValueRange operands,
15
                               ValueRange results)
16
    : map(map), operands(operands.begin(), operands.end()),
17
0
      results(results.begin(), results.end()) {}
18
19
void AffineValueMap::reset(AffineMap map, ValueRange operands,
20
0
                           ValueRange results) {
21
0
  this->map.reset(map);
22
0
  this->operands.assign(operands.begin(), operands.end());
23
0
  this->results.assign(results.begin(), results.end());
24
0
}
25
26
void AffineValueMap::difference(const AffineValueMap &a,
27
                                const AffineValueMap &b, AffineValueMap *res) {
28
  assert(a.getNumResults() == b.getNumResults() && "invalid inputs");
29
30
  // Fully compose A's map + operands.
31
  auto aMap = a.getAffineMap();
32
  SmallVector<Value, 4> aOperands(a.getOperands().begin(),
33
                                  a.getOperands().end());
34
  fullyComposeAffineMapAndOperands(&aMap, &aOperands);
35
36
  // Use the affine apply normalizer to get B's map into A's coordinate space.
37
  AffineApplyNormalizer normalizer(aMap, aOperands);
38
  SmallVector<Value, 4> bOperands(b.getOperands().begin(),
39
                                  b.getOperands().end());
40
  auto bMap = b.getAffineMap();
41
  normalizer.normalize(&bMap, &bOperands);
42
43
  assert(std::equal(bOperands.begin(), bOperands.end(),
44
                    normalizer.getOperands().begin()) &&
45
         "operands are expected to be the same after normalization");
46
47
  // Construct the difference expressions.
48
  SmallVector<AffineExpr, 4> diffExprs;
49
  diffExprs.reserve(a.getNumResults());
50
  for (unsigned i = 0, e = bMap.getNumResults(); i < e; ++i)
51
    diffExprs.push_back(normalizer.getAffineMap().getResult(i) -
52
                        bMap.getResult(i));
53
54
  auto diffMap =
55
      AffineMap::get(normalizer.getNumDims(), normalizer.getNumSymbols(),
56
                     diffExprs, aMap.getContext());
57
  canonicalizeMapAndOperands(&diffMap, &bOperands);
58
  diffMap = simplifyAffineMap(diffMap);
59
  res->reset(diffMap, bOperands);
60
}
61
62
// Returns true and sets 'indexOfMatch' if 'valueToMatch' is found in
63
// 'valuesToSearch' beginning at 'indexStart'. Returns false otherwise.
64
static bool findIndex(Value valueToMatch, ArrayRef<Value> valuesToSearch,
65
0
                      unsigned indexStart, unsigned *indexOfMatch) {
66
0
  unsigned size = valuesToSearch.size();
67
0
  for (unsigned i = indexStart; i < size; ++i) {
68
0
    if (valueToMatch == valuesToSearch[i]) {
69
0
      *indexOfMatch = i;
70
0
      return true;
71
0
    }
72
0
  }
73
0
  return false;
74
0
}
75
76
0
bool AffineValueMap::isMultipleOf(unsigned idx, int64_t factor) const {
77
0
  return map.isMultipleOf(idx, factor);
78
0
}
79
80
/// This method uses the invariant that operands are always positionally aligned
81
/// with the AffineDimExpr in the underlying AffineMap.
82
0
bool AffineValueMap::isFunctionOf(unsigned idx, Value value) const {
83
0
  unsigned index;
84
0
  if (!findIndex(value, operands, /*indexStart=*/0, &index)) {
85
0
    return false;
86
0
  }
87
0
  auto expr = const_cast<AffineValueMap *>(this)->getAffineMap().getResult(idx);
88
0
  // TODO(ntv): this is better implemented on a flattened representation.
89
0
  // At least for now it is conservative.
90
0
  return expr.isFunctionOfDim(index);
91
0
}
92
93
0
Value AffineValueMap::getOperand(unsigned i) const {
94
0
  return static_cast<Value>(operands[i]);
95
0
}
96
97
0
ArrayRef<Value> AffineValueMap::getOperands() const {
98
0
  return ArrayRef<Value>(operands);
99
0
}
100
101
0
AffineMap AffineValueMap::getAffineMap() const { return map.getAffineMap(); }
102
103
0
AffineValueMap::~AffineValueMap() {}