//===- DXILOpBuilder.cpp - Helper class for build DIXLOp functions --------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file This file contains class to help build DXIL op functions.
//===----------------------------------------------------------------------===//

#include "DXILOpBuilder.h"
#include "DXILConstants.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/DXILOperationCommon.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;
using namespace llvm::dxil;

constexpr StringLiteral DXILOpNamePrefix = "dx.op.";

namespace {

enum OverloadKind : uint16_t {
  VOID = 1,
  HALF = 1 << 1,
  FLOAT = 1 << 2,
  DOUBLE = 1 << 3,
  I1 = 1 << 4,
  I8 = 1 << 5,
  I16 = 1 << 6,
  I32 = 1 << 7,
  I64 = 1 << 8,
  UserDefineType = 1 << 9,
  ObjectType = 1 << 10,
};

} // namespace

static const char *getOverloadTypeName(OverloadKind Kind) {
  switch (Kind) {
  case OverloadKind::HALF:
    return "f16";
  case OverloadKind::FLOAT:
    return "f32";
  case OverloadKind::DOUBLE:
    return "f64";
  case OverloadKind::I1:
    return "i1";
  case OverloadKind::I8:
    return "i8";
  case OverloadKind::I16:
    return "i16";
  case OverloadKind::I32:
    return "i32";
  case OverloadKind::I64:
    return "i64";
  case OverloadKind::VOID:
  case OverloadKind::ObjectType:
  case OverloadKind::UserDefineType:
    break;
  }
  llvm_unreachable("invalid overload type for name");
  return "void";
}

static OverloadKind getOverloadKind(Type *Ty) {
  Type::TypeID T = Ty->getTypeID();
  switch (T) {
  case Type::VoidTyID:
    return OverloadKind::VOID;
  case Type::HalfTyID:
    return OverloadKind::HALF;
  case Type::FloatTyID:
    return OverloadKind::FLOAT;
  case Type::DoubleTyID:
    return OverloadKind::DOUBLE;
  case Type::IntegerTyID: {
    IntegerType *ITy = cast<IntegerType>(Ty);
    unsigned Bits = ITy->getBitWidth();
    switch (Bits) {
    case 1:
      return OverloadKind::I1;
    case 8:
      return OverloadKind::I8;
    case 16:
      return OverloadKind::I16;
    case 32:
      return OverloadKind::I32;
    case 64:
      return OverloadKind::I64;
    default:
      llvm_unreachable("invalid overload type");
      return OverloadKind::VOID;
    }
  }
  case Type::PointerTyID:
    return OverloadKind::UserDefineType;
  case Type::StructTyID:
    return OverloadKind::ObjectType;
  default:
    llvm_unreachable("invalid overload type");
    return OverloadKind::VOID;
  }
}

static std::string getTypeName(OverloadKind Kind, Type *Ty) {
  if (Kind < OverloadKind::UserDefineType) {
    return getOverloadTypeName(Kind);
  } else if (Kind == OverloadKind::UserDefineType) {
    StructType *ST = cast<StructType>(Ty);
    return ST->getStructName().str();
  } else if (Kind == OverloadKind::ObjectType) {
    StructType *ST = cast<StructType>(Ty);
    return ST->getStructName().str();
  } else {
    std::string Str;
    raw_string_ostream OS(Str);
    Ty->print(OS);
    return OS.str();
  }
}

// Static properties.
struct OpCodeProperty {
  dxil::OpCode OpCode;
  // Offset in DXILOpCodeNameTable.
  unsigned OpCodeNameOffset;
  dxil::OpCodeClass OpCodeClass;
  // Offset in DXILOpCodeClassNameTable.
  unsigned OpCodeClassNameOffset;
  uint16_t OverloadTys;
  llvm::Attribute::AttrKind FuncAttr;
  int OverloadParamIndex;        // parameter index which control the overload.
                                 // When < 0, should be only 1 overload type.
  unsigned NumOfParameters;      // Number of parameters include return value.
  unsigned ParameterTableOffset; // Offset in ParameterTable.
};

// Include getOpCodeClassName getOpCodeProperty, getOpCodeName and
// getOpCodeParameterKind which generated by tableGen.
#define DXIL_OP_OPERATION_TABLE
#include "DXILOperation.inc"
#undef DXIL_OP_OPERATION_TABLE

static std::string constructOverloadName(OverloadKind Kind, Type *Ty,
                                         const OpCodeProperty &Prop) {
  if (Kind == OverloadKind::VOID) {
    return (Twine(DXILOpNamePrefix) + getOpCodeClassName(Prop)).str();
  }
  return (Twine(DXILOpNamePrefix) + getOpCodeClassName(Prop) + "." +
          getTypeName(Kind, Ty))
      .str();
}

static std::string constructOverloadTypeName(OverloadKind Kind,
                                             StringRef TypeName) {
  if (Kind == OverloadKind::VOID)
    return TypeName.str();

  assert(Kind < OverloadKind::UserDefineType && "invalid overload kind");
  return (Twine(TypeName) + getOverloadTypeName(Kind)).str();
}

static StructType *getOrCreateStructType(StringRef Name,
                                         ArrayRef<Type *> EltTys,
                                         LLVMContext &Ctx) {
  StructType *ST = StructType::getTypeByName(Ctx, Name);
  if (ST)
    return ST;

  return StructType::create(Ctx, EltTys, Name);
}

static StructType *getResRetType(Type *OverloadTy, LLVMContext &Ctx) {
  OverloadKind Kind = getOverloadKind(OverloadTy);
  std::string TypeName = constructOverloadTypeName(Kind, "dx.types.ResRet.");
  Type *FieldTypes[5] = {OverloadTy, OverloadTy, OverloadTy, OverloadTy,
                         Type::getInt32Ty(Ctx)};
  return getOrCreateStructType(TypeName, FieldTypes, Ctx);
}

static StructType *getHandleType(LLVMContext &Ctx) {
  return getOrCreateStructType("dx.types.Handle", Type::getInt8PtrTy(Ctx), Ctx);
}

static Type *getTypeFromParameterKind(ParameterKind Kind, Type *OverloadTy) {
  auto &Ctx = OverloadTy->getContext();
  switch (Kind) {
  case ParameterKind::VOID:
    return Type::getVoidTy(Ctx);
  case ParameterKind::HALF:
    return Type::getHalfTy(Ctx);
  case ParameterKind::FLOAT:
    return Type::getFloatTy(Ctx);
  case ParameterKind::DOUBLE:
    return Type::getDoubleTy(Ctx);
  case ParameterKind::I1:
    return Type::getInt1Ty(Ctx);
  case ParameterKind::I8:
    return Type::getInt8Ty(Ctx);
  case ParameterKind::I16:
    return Type::getInt16Ty(Ctx);
  case ParameterKind::I32:
    return Type::getInt32Ty(Ctx);
  case ParameterKind::I64:
    return Type::getInt64Ty(Ctx);
  case ParameterKind::OVERLOAD:
    return OverloadTy;
  case ParameterKind::RESOURCE_RET:
    return getResRetType(OverloadTy, Ctx);
  case ParameterKind::DXIL_HANDLE:
    return getHandleType(Ctx);
  default:
    break;
  }
  llvm_unreachable("Invalid parameter kind");
  return nullptr;
}

static FunctionType *getDXILOpFunctionType(const OpCodeProperty *Prop,
                                           Type *OverloadTy) {
  SmallVector<Type *> ArgTys;

  auto ParamKinds = getOpCodeParameterKind(*Prop);

  for (unsigned I = 0; I < Prop->NumOfParameters; ++I) {
    ParameterKind Kind = ParamKinds[I];
    ArgTys.emplace_back(getTypeFromParameterKind(Kind, OverloadTy));
  }
  return FunctionType::get(
      ArgTys[0], ArrayRef<Type *>(&ArgTys[1], ArgTys.size() - 1), false);
}

static FunctionCallee getOrCreateDXILOpFunction(dxil::OpCode DXILOp,
                                                Type *OverloadTy, Module &M) {
  const OpCodeProperty *Prop = getOpCodeProperty(DXILOp);

  OverloadKind Kind = getOverloadKind(OverloadTy);
  // FIXME: find the issue and report error in clang instead of check it in
  // backend.
  if ((Prop->OverloadTys & (uint16_t)Kind) == 0) {
    llvm_unreachable("invalid overload");
  }

  std::string FnName = constructOverloadName(Kind, OverloadTy, *Prop);
  // Dependent on name to dedup.
  if (auto *Fn = M.getFunction(FnName))
    return FunctionCallee(Fn);

  FunctionType *DXILOpFT = getDXILOpFunctionType(Prop, OverloadTy);
  return M.getOrInsertFunction(FnName, DXILOpFT);
}

namespace llvm {
namespace dxil {

CallInst *DXILOpBuilder::createDXILOpCall(dxil::OpCode OpCode, Type *OverloadTy,
                                          llvm::iterator_range<Use *> Args) {
  auto Fn = getOrCreateDXILOpFunction(OpCode, OverloadTy, M);
  SmallVector<Value *> FullArgs;
  FullArgs.emplace_back(B.getInt32((int32_t)OpCode));
  FullArgs.append(Args.begin(), Args.end());
  return B.CreateCall(Fn, FullArgs);
}

Type *DXILOpBuilder::getOverloadTy(dxil::OpCode OpCode, FunctionType *FT,
                                   bool NoOpCodeParam) {

  const OpCodeProperty *Prop = getOpCodeProperty(OpCode);
  if (Prop->OverloadParamIndex < 0) {
    auto &Ctx = FT->getContext();
    // When only has 1 overload type, just return it.
    switch (Prop->OverloadTys) {
    case OverloadKind::VOID:
      return Type::getVoidTy(Ctx);
    case OverloadKind::HALF:
      return Type::getHalfTy(Ctx);
    case OverloadKind::FLOAT:
      return Type::getFloatTy(Ctx);
    case OverloadKind::DOUBLE:
      return Type::getDoubleTy(Ctx);
    case OverloadKind::I1:
      return Type::getInt1Ty(Ctx);
    case OverloadKind::I8:
      return Type::getInt8Ty(Ctx);
    case OverloadKind::I16:
      return Type::getInt16Ty(Ctx);
    case OverloadKind::I32:
      return Type::getInt32Ty(Ctx);
    case OverloadKind::I64:
      return Type::getInt64Ty(Ctx);
    default:
      llvm_unreachable("invalid overload type");
      return nullptr;
    }
  }

  // Prop->OverloadParamIndex is 0, overload type is FT->getReturnType().
  Type *OverloadType = FT->getReturnType();
  if (Prop->OverloadParamIndex != 0) {
    // Skip Return Type and Type for DXIL opcode.
    const unsigned SkipedParam = NoOpCodeParam ? 2 : 1;
    OverloadType = FT->getParamType(Prop->OverloadParamIndex - SkipedParam);
  }

  auto ParamKinds = getOpCodeParameterKind(*Prop);
  auto Kind = ParamKinds[Prop->OverloadParamIndex];
  // For ResRet and CBufferRet, OverloadTy is in field of StructType.
  if (Kind == ParameterKind::CBUFFER_RET ||
      Kind == ParameterKind::RESOURCE_RET) {
    auto *ST = cast<StructType>(OverloadType);
    OverloadType = ST->getElementType(0);
  }
  return OverloadType;
}

const char *DXILOpBuilder::getOpCodeName(dxil::OpCode DXILOp) {
  return ::getOpCodeName(DXILOp);
}
} // namespace dxil
} // namespace llvm
