//===-- KindMapping.cpp ---------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
//
//===----------------------------------------------------------------------===//

#include "flang/Optimizer/Support/KindMapping.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "llvm/Support/CommandLine.h"

/// Allow the user to set the FIR intrinsic type kind value to LLVM type
/// mappings.  Note that these are not mappings from kind values to any
/// other MLIR dialect, only to LLVM IR. The default values follow the f18
/// front-end kind mappings.

using Bitsize = fir::KindMapping::Bitsize;
using KindTy = fir::KindMapping::KindTy;
using LLVMTypeID = fir::KindMapping::LLVMTypeID;
using MatchResult = fir::KindMapping::MatchResult;

static llvm::cl::opt<std::string>
    clKindMapping("kind-mapping",
                  llvm::cl::desc("kind mapping string to set kind precision"),
                  llvm::cl::value_desc("kind-mapping-string"),
                  llvm::cl::init(fir::KindMapping::getDefaultMap()));

static llvm::cl::opt<std::string>
    clDefaultKinds("default-kinds",
                   llvm::cl::desc("string to set default kind values"),
                   llvm::cl::value_desc("default-kind-string"),
                   llvm::cl::init(fir::KindMapping::getDefaultKinds()));

// Keywords for the floating point types.

static constexpr const char *kwHalf = "Half";
static constexpr const char *kwBFloat = "BFloat";
static constexpr const char *kwFloat = "Float";
static constexpr const char *kwDouble = "Double";
static constexpr const char *kwX86FP80 = "X86_FP80";
static constexpr const char *kwFP128 = "FP128";
static constexpr const char *kwPPCFP128 = "PPC_FP128";

/// Integral types default to the kind value being the size of the value in
/// bytes. The default is to scale from bytes to bits.
static Bitsize defaultScalingKind(KindTy kind) {
  const unsigned bitsInByte = 8;
  return kind * bitsInByte;
}

/// Floating-point types default to the kind value being the size of the value
/// in bytes. The default is to translate kinds of 2, 3, 4, 8, 10, and 16 to a
/// valid llvm::Type::TypeID value. Otherwise, the default is FloatTyID.
static LLVMTypeID defaultRealKind(KindTy kind) {
  switch (kind) {
  case 2:
    return LLVMTypeID::HalfTyID;
  case 3:
    return LLVMTypeID::BFloatTyID;
  case 4:
    return LLVMTypeID::FloatTyID;
  case 8:
    return LLVMTypeID::DoubleTyID;
  case 10:
    return LLVMTypeID::X86_FP80TyID;
  case 16:
    return LLVMTypeID::FP128TyID;
  default:
    return LLVMTypeID::FloatTyID;
  }
}

// lookup the kind-value given the defaults, the mappings, and a KIND key
template <typename RT, char KEY>
static RT doLookup(std::function<RT(KindTy)> def,
                   const llvm::DenseMap<std::pair<char, KindTy>, RT> &map,
                   KindTy kind) {
  std::pair<char, KindTy> key{KEY, kind};
  auto iter = map.find(key);
  if (iter != map.end())
    return iter->second;
  return def(kind);
}

// do a lookup for INTERGER, LOGICAL, or CHARACTER
template <char KEY, typename MAP>
static Bitsize getIntegerLikeBitsize(KindTy kind, const MAP &map) {
  return doLookup<Bitsize, KEY>(defaultScalingKind, map, kind);
}

// do a lookup for REAL or COMPLEX
template <char KEY, typename MAP>
static LLVMTypeID getFloatLikeTypeID(KindTy kind, const MAP &map) {
  return doLookup<LLVMTypeID, KEY>(defaultRealKind, map, kind);
}

template <char KEY, typename MAP>
static const llvm::fltSemantics &getFloatSemanticsOfKind(KindTy kind,
                                                         const MAP &map) {
  switch (doLookup<LLVMTypeID, KEY>(defaultRealKind, map, kind)) {
  case LLVMTypeID::HalfTyID:
    return llvm::APFloat::IEEEhalf();
  case LLVMTypeID::BFloatTyID:
    return llvm::APFloat::BFloat();
  case LLVMTypeID::FloatTyID:
    return llvm::APFloat::IEEEsingle();
  case LLVMTypeID::DoubleTyID:
    return llvm::APFloat::IEEEdouble();
  case LLVMTypeID::X86_FP80TyID:
    return llvm::APFloat::x87DoubleExtended();
  case LLVMTypeID::FP128TyID:
    return llvm::APFloat::IEEEquad();
  case LLVMTypeID::PPC_FP128TyID:
    return llvm::APFloat::PPCDoubleDouble();
  default:
    llvm_unreachable("Invalid floating type");
  }
}

/// Parse an intrinsic type code. The codes are ('a', CHARACTER), ('c',
/// COMPLEX), ('i', INTEGER), ('l', LOGICAL), and ('r', REAL).
static MatchResult parseCode(char &code, const char *&ptr, const char *endPtr) {
  if (ptr >= endPtr)
    return mlir::failure();
  if (*ptr != 'a' && *ptr != 'c' && *ptr != 'i' && *ptr != 'l' && *ptr != 'r')
    return mlir::failure();
  code = *ptr++;
  return mlir::success();
}

/// Same as `parseCode` but adds the ('d', DOUBLE PRECISION) code.
static MatchResult parseDefCode(char &code, const char *&ptr,
                                const char *endPtr) {
  if (ptr >= endPtr)
    return mlir::failure();
  if (*ptr == 'd') {
    code = *ptr++;
    return mlir::success();
  }
  return parseCode(code, ptr, endPtr);
}

template <char ch>
static MatchResult parseSingleChar(const char *&ptr, const char *endPtr) {
  if (ptr >= endPtr || *ptr != ch)
    return mlir::failure();
  ++ptr;
  return mlir::success();
}

static MatchResult parseColon(const char *&ptr, const char *endPtr) {
  return parseSingleChar<':'>(ptr, endPtr);
}

static MatchResult parseComma(const char *&ptr, const char *endPtr) {
  return parseSingleChar<','>(ptr, endPtr);
}

/// Recognize and parse an unsigned integer.
static MatchResult parseInt(unsigned &result, const char *&ptr,
                            const char *endPtr) {
  const char *beg = ptr;
  while (ptr < endPtr && *ptr >= '0' && *ptr <= '9')
    ptr++;
  if (beg == ptr)
    return mlir::failure();
  llvm::StringRef ref(beg, ptr - beg);
  int temp;
  if (ref.consumeInteger(10, temp))
    return mlir::failure();
  result = temp;
  return mlir::success();
}

static mlir::LogicalResult matchString(const char *&ptr, const char *endPtr,
                                       llvm::StringRef literal) {
  llvm::StringRef s(ptr, endPtr - ptr);
  if (s.startswith(literal)) {
    ptr += literal.size();
    return mlir::success();
  }
  return mlir::failure();
}

/// Recognize and parse the various floating-point keywords. These follow the
/// LLVM naming convention.
static MatchResult parseTypeID(LLVMTypeID &result, const char *&ptr,
                               const char *endPtr) {
  if (mlir::succeeded(matchString(ptr, endPtr, kwHalf))) {
    result = LLVMTypeID::HalfTyID;
    return mlir::success();
  }
  if (mlir::succeeded(matchString(ptr, endPtr, kwBFloat))) {
    result = LLVMTypeID::BFloatTyID;
    return mlir::success();
  }
  if (mlir::succeeded(matchString(ptr, endPtr, kwFloat))) {
    result = LLVMTypeID::FloatTyID;
    return mlir::success();
  }
  if (mlir::succeeded(matchString(ptr, endPtr, kwDouble))) {
    result = LLVMTypeID::DoubleTyID;
    return mlir::success();
  }
  if (mlir::succeeded(matchString(ptr, endPtr, kwX86FP80))) {
    result = LLVMTypeID::X86_FP80TyID;
    return mlir::success();
  }
  if (mlir::succeeded(matchString(ptr, endPtr, kwFP128))) {
    result = LLVMTypeID::FP128TyID;
    return mlir::success();
  }
  if (mlir::succeeded(matchString(ptr, endPtr, kwPPCFP128))) {
    result = LLVMTypeID::PPC_FP128TyID;
    return mlir::success();
  }
  return mlir::failure();
}

fir::KindMapping::KindMapping(mlir::MLIRContext *context, llvm::StringRef map,
                              llvm::ArrayRef<KindTy> defs)
    : context{context} {
  if (mlir::failed(setDefaultKinds(defs)))
    llvm::report_fatal_error("bad default kinds");
  if (mlir::failed(parse(map)))
    llvm::report_fatal_error("could not parse kind map");
}

fir::KindMapping::KindMapping(mlir::MLIRContext *context,
                              llvm::ArrayRef<KindTy> defs)
    : KindMapping{context, clKindMapping, defs} {}

fir::KindMapping::KindMapping(mlir::MLIRContext *context)
    : KindMapping{context, clKindMapping, clDefaultKinds} {}

MatchResult fir::KindMapping::badMapString(const llvm::Twine &ptr) {
  auto unknown = mlir::UnknownLoc::get(context);
  mlir::emitError(unknown, ptr);
  return mlir::failure();
}

MatchResult fir::KindMapping::parse(llvm::StringRef kindMap) {
  if (kindMap.empty())
    return mlir::success();
  const char *srcPtr = kindMap.begin();
  const char *endPtr = kindMap.end();
  while (true) {
    char code = '\0';
    KindTy kind = 0;
    if (parseCode(code, srcPtr, endPtr) || parseInt(kind, srcPtr, endPtr))
      return badMapString(srcPtr);
    if (code == 'a' || code == 'i' || code == 'l') {
      Bitsize bits = 0;
      if (parseColon(srcPtr, endPtr) || parseInt(bits, srcPtr, endPtr))
        return badMapString(srcPtr);
      intMap[std::pair<char, KindTy>{code, kind}] = bits;
    } else if (code == 'r' || code == 'c') {
      LLVMTypeID id{};
      if (parseColon(srcPtr, endPtr) || parseTypeID(id, srcPtr, endPtr))
        return badMapString(srcPtr);
      floatMap[std::pair<char, KindTy>{code, kind}] = id;
    } else {
      return badMapString(srcPtr);
    }
    if (parseComma(srcPtr, endPtr))
      break;
  }
  if (srcPtr > endPtr)
    return badMapString(srcPtr);
  return mlir::success();
}

Bitsize fir::KindMapping::getCharacterBitsize(KindTy kind) const {
  return getIntegerLikeBitsize<'a'>(kind, intMap);
}

Bitsize fir::KindMapping::getIntegerBitsize(KindTy kind) const {
  return getIntegerLikeBitsize<'i'>(kind, intMap);
}

Bitsize fir::KindMapping::getLogicalBitsize(KindTy kind) const {
  return getIntegerLikeBitsize<'l'>(kind, intMap);
}

LLVMTypeID fir::KindMapping::getRealTypeID(KindTy kind) const {
  return getFloatLikeTypeID<'r'>(kind, floatMap);
}

LLVMTypeID fir::KindMapping::getComplexTypeID(KindTy kind) const {
  return getFloatLikeTypeID<'c'>(kind, floatMap);
}

Bitsize fir::KindMapping::getRealBitsize(KindTy kind) const {
  auto typeId = getFloatLikeTypeID<'r'>(kind, floatMap);
  llvm::LLVMContext llCtxt; // FIXME
  return llvm::Type::getPrimitiveType(llCtxt, typeId)->getPrimitiveSizeInBits();
}

const llvm::fltSemantics &
fir::KindMapping::getFloatSemantics(KindTy kind) const {
  return getFloatSemanticsOfKind<'r'>(kind, floatMap);
}

std::string fir::KindMapping::mapToString() const {
  std::string result;
  bool addComma = false;
  for (auto [k, v] : intMap) {
    if (addComma)
      result.append(",");
    else
      addComma = true;
    result += k.first + std::to_string(k.second) + ":" + std::to_string(v);
  }
  for (auto [k, v] : floatMap) {
    if (addComma)
      result.append(",");
    else
      addComma = true;
    result.append(k.first + std::to_string(k.second) + ":");
    switch (v) {
    default:
      llvm_unreachable("unhandled type-id");
    case LLVMTypeID::HalfTyID:
      result.append(kwHalf);
      break;
    case LLVMTypeID::BFloatTyID:
      result.append(kwBFloat);
      break;
    case LLVMTypeID::FloatTyID:
      result.append(kwFloat);
      break;
    case LLVMTypeID::DoubleTyID:
      result.append(kwDouble);
      break;
    case LLVMTypeID::X86_FP80TyID:
      result.append(kwX86FP80);
      break;
    case LLVMTypeID::FP128TyID:
      result.append(kwFP128);
      break;
    case LLVMTypeID::PPC_FP128TyID:
      result.append(kwPPCFP128);
      break;
    }
  }
  return result;
}

mlir::LogicalResult
fir::KindMapping::setDefaultKinds(llvm::ArrayRef<KindTy> defs) {
  if (defs.empty()) {
    // generic front-end defaults
    const KindTy genericKind = 4;
    defaultMap.insert({'a', 1});
    defaultMap.insert({'c', genericKind});
    defaultMap.insert({'d', 2 * genericKind});
    defaultMap.insert({'i', genericKind});
    defaultMap.insert({'l', genericKind});
    defaultMap.insert({'r', genericKind});
    return mlir::success();
  }
  if (defs.size() != 6)
    return mlir::failure();

  // defaults determined after command-line processing
  defaultMap.insert({'a', defs[0]});
  defaultMap.insert({'c', defs[1]});
  defaultMap.insert({'d', defs[2]});
  defaultMap.insert({'i', defs[3]});
  defaultMap.insert({'l', defs[4]});
  defaultMap.insert({'r', defs[5]});
  return mlir::success();
}

std::string fir::KindMapping::defaultsToString() const {
  return std::string("a") + std::to_string(defaultMap.find('a')->second) +
         std::string("c") + std::to_string(defaultMap.find('c')->second) +
         std::string("d") + std::to_string(defaultMap.find('d')->second) +
         std::string("i") + std::to_string(defaultMap.find('i')->second) +
         std::string("l") + std::to_string(defaultMap.find('l')->second) +
         std::string("r") + std::to_string(defaultMap.find('r')->second);
}

/// Convert a default intrinsic code into the proper position in the array. The
/// default kinds have a precise ordering.
static int codeToIndex(char code) {
  switch (code) {
  case 'a':
    return 0;
  case 'c':
    return 1;
  case 'd':
    return 2;
  case 'i':
    return 3;
  case 'l':
    return 4;
  case 'r':
    return 5;
  }
  llvm_unreachable("invalid default kind intrinsic code");
}

std::vector<KindTy> fir::KindMapping::toDefaultKinds(llvm::StringRef defs) {
  std::vector<KindTy> result(6);
  char code;
  KindTy kind;
  if (defs.empty())
    defs = clDefaultKinds;
  const char *srcPtr = defs.begin();
  const char *endPtr = defs.end();
  while (srcPtr < endPtr) {
    if (parseDefCode(code, srcPtr, endPtr) || parseInt(kind, srcPtr, endPtr))
      llvm::report_fatal_error("invalid default kind code");
    result[codeToIndex(code)] = kind;
  }
  assert(srcPtr == endPtr);
  return result;
}

KindTy fir::KindMapping::defaultCharacterKind() const {
  auto iter = defaultMap.find('a');
  assert(iter != defaultMap.end());
  return iter->second;
}

KindTy fir::KindMapping::defaultComplexKind() const {
  auto iter = defaultMap.find('c');
  assert(iter != defaultMap.end());
  return iter->second;
}

KindTy fir::KindMapping::defaultDoubleKind() const {
  auto iter = defaultMap.find('d');
  assert(iter != defaultMap.end());
  return iter->second;
}

KindTy fir::KindMapping::defaultIntegerKind() const {
  auto iter = defaultMap.find('i');
  assert(iter != defaultMap.end());
  return iter->second;
}

KindTy fir::KindMapping::defaultLogicalKind() const {
  auto iter = defaultMap.find('l');
  assert(iter != defaultMap.end());
  return iter->second;
}

KindTy fir::KindMapping::defaultRealKind() const {
  auto iter = defaultMap.find('r');
  assert(iter != defaultMap.end());
  return iter->second;
}
