//===- IndexingMapOpInterface.cpp -- IndexingMapOpInterface impl ----------===//
//
// 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/Interfaces/IndexingMapOpInterface.h"

using namespace mlir;

namespace mlir {
#include "mlir/Interfaces/IndexingMapOpInterface.cpp.inc"
} // namespace mlir

static LogicalResult verifyIndexingMapOperandType(Operation *op, Type t,
                                                  unsigned operandNumber) {
  // Non-shaped types are treated as scalars (rank-0). This includes builtin
  // types (integer, float, complex) as well as custom dialect types.
  if (!isa<ShapedType>(t))
    return success();

  // Vectors are allowed.
  if (isa<VectorType>(t))
    return success();

  // MemRefs: must be ranked.
  if (isa<UnrankedMemRefType>(t)) {
    return op->emitOpError("operand #")
           << operandNumber << " must be a ranked memref, but got " << t;
  }
  if (isa<MemRefType>(t))
    return success();

  // Tensors: must be ranked.
  if (isa<UnrankedTensorType>(t)) {
    return op->emitOpError("operand #")
           << operandNumber << " must be a ranked tensor, but got " << t;
  }
  if (isa<RankedTensorType>(t))
    return success();

  // Any other shaped type is not supported by this interface.
  return op->emitOpError("operand #")
         << operandNumber
         << " must be ranked tensor/memref, vector, or scalar, but got " << t;
}

LogicalResult mlir::IndexingMapOpInterface::verifyImpl() {
  // All input/output operands must be indexed.
  if (static_cast<int64_t>(getIndexingMapsArray().size()) !=
      getOperation()->getNumOperands())
    return this->emitOpError("expected the number of indexing_map (")
           << getIndexingMapsArray().size()
           << ") to be equal to the number of input/output operands ("
           << getOperation()->getNumOperands() << ")";

  // Inline size chosen empirically based on compilation profiling.
  // Profiled: 7.5M calls, avg=5.9+-3.1. N=8 covers 67% of cases inline.
  SmallVector<int64_t, 8> allShapesSizes;

  for (OpOperand &opOperand : getOperation()->getOpOperands()) {
    Type ty = opOperand.get().getType();
    if (failed(verifyIndexingMapOperandType(getOperation(), ty,
                                            opOperand.getOperandNumber())))
      return failure();
    AffineMap indexingMap = getMatchingIndexingMap(&opOperand);
    // Symbols disallowed.
    if (indexingMap.getNumSymbols() != 0)
      return this->emitOpError("unexpected symbols in indexing_map #")
             << opOperand.getOperandNumber();
    // Handle scalars (non-shaped types: integer, float, complex, custom types,
    // etc.).
    if (!isa<ShapedType>(ty)) {
      int64_t rank = 0;
      if (indexingMap.getNumResults() != rank)
        return this->emitOpError("expected operand #")
               << opOperand.getOperandNumber() << " rank (" << rank
               << ") to match the result rank of indexing_map ("
               << indexingMap.getNumResults() << ")";
      continue;
    }
    SmallVector<int64_t> shape = getStaticOperandShape(&opOperand);
    int64_t rank = shape.size();

    // Result rank must match operand rank.
    if (indexingMap.getNumResults() != rank)
      return this->emitOpError("expected operand #")
             << opOperand.getOperandNumber() << " rank (" << rank
             << ") to match the result rank of indexing_map ("
             << indexingMap.getNumResults() << ")";

    llvm::append_range(allShapesSizes, shape);
  }

  AffineMap invertedMap = getShapesToLoopsMap();
  if (!invertedMap) {
    std::string str;
    llvm::raw_string_ostream os(str);
    getLoopsToShapesMap().print(os);
    return this->emitOpError("invalid indexing maps are non-invertible: ")
           << "(" << str << ")";
  }

  SmallVector<int64_t> endLoopRangeValues = invertedMap.compose(allShapesSizes);

  // Check if given shapes match to inferred shapes.
  SmallVector<int64_t> startLoopRangeValues(endLoopRangeValues.size(), 0);
  // Verify only static cases since we can't get exact dimension sizes and
  // loop ranges for dynamic cases in this stage.
  if (llvm::none_of(endLoopRangeValues, ShapedType::isDynamic)) {
    // Exclusive end range.
    for (int64_t &range : endLoopRangeValues)
      range -= 1;
    for (OpOperand &opOperand : getOperation()->getOpOperands()) {
      AffineMap indexingMap = getMatchingIndexingMap(&opOperand);
      SmallVector<int64_t> startIndices =
          indexingMap.compose(startLoopRangeValues);
      SmallVector<int64_t> endIndices = indexingMap.compose(endLoopRangeValues);
      SmallVector<int64_t> shape = getStaticOperandShape(&opOperand);
      for (auto dim : llvm::seq<int64_t>(0, shape.size())) {
        // Ignore dynamic dimension or the case that the dimension size is 0
        if (ShapedType::isDynamic(shape[dim]) || shape[dim] == 0)
          continue;

        // The first index or last index should be the maximum or the minimum in
        // the inferred index ranges since the range is increasing or
        // decreasing. The size of dimensions of input/output operands and the
        // maximum value + 1 in the inferred range should be the same. But, for
        // now we check if the inferred ranges are in boundary of input/output
        // operands' size or not in case that Affine Expressions are complicated
        // such as d0 * 3
        // + d1 since it is not easy to handle the issues.
        // Found the case that this solution can't check, for example, (d0, d1)
        // -> (d1 - d0)
        int64_t inferredDimSize =
            std::max(startIndices[dim], endIndices[dim]) + 1;
        if (std::min(startIndices[dim], endIndices[dim]) < 0) {
          std::string mapStr;
          {
            llvm::raw_string_ostream os(mapStr);
            os << indexingMap;
          }
          return this->emitOpError(
                     "unexpected result less than 0 at expression #")
                 << dim << " in " << mapStr;
        }
        if (isa<AffineDimExpr>(indexingMap.getResult(dim))) {
          if (inferredDimSize != shape[dim]) {
            return this->emitOpError("inferred input/output operand #")
                   << opOperand.getOperandNumber() << " has shape's dimension #"
                   << dim << " to be " << inferredDimSize << ", but found "
                   << shape[dim];
          }
        } else {
          if (inferredDimSize > shape[dim]) {
            return this->emitOpError("inferred input/output operand #")
                   << opOperand.getOperandNumber() << " has shape's dimension #"
                   << dim << " to be greater than or equal to "
                   << inferredDimSize << ", but found " << shape[dim];
          }
        }
      }
    }
  }

  return success();
}
