//===- 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;

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::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() {}
