//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend generates hlsl_alias_intrinsics_gen.inc (alias
// overloads) and hlsl_inline_intrinsics_gen.inc (inline/detail overloads) for
// HLSL intrinsic functions.
//
//===----------------------------------------------------------------------===//

#include "TableGenBackends.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Record.h"

using namespace llvm;

/// Minimum shader model version that supports 16-bit types.
static constexpr StringLiteral SM6_2 = "6.2";

//===----------------------------------------------------------------------===//
// Type name helpers
//===----------------------------------------------------------------------===//

static std::string getVectorTypeName(StringRef ElemType, unsigned N) {
  return (ElemType + Twine(N)).str();
}

static std::string getMatrixTypeName(StringRef ElemType, unsigned Rows,
                                     unsigned Cols) {
  return (ElemType + Twine(Rows) + "x" + Twine(Cols)).str();
}

/// Get the fixed type name string for a VectorType or HLSLType record.
static std::string getFixedTypeName(const Record *R) {
  if (R->isSubClassOf("VectorType"))
    return getVectorTypeName(
        R->getValueAsDef("ElementType")->getValueAsString("Name"),
        R->getValueAsInt("Size"));
  assert(R->isSubClassOf("HLSLType"));
  return R->getValueAsString("Name").str();
}

/// For a VectorType, return its ElementType record; for an HLSLType, return
/// the record itself (it is already a scalar element type).
static const Record *getElementTypeRecord(const Record *R) {
  if (R->isSubClassOf("VectorType"))
    return R->getValueAsDef("ElementType");
  assert(R->isSubClassOf("HLSLType"));
  return R;
}

//===----------------------------------------------------------------------===//
// Type information
//===----------------------------------------------------------------------===//

namespace {

/// Classifies how a type varies across overloads.
enum TypeKindEnum {
  TK_Varying = 0,      ///< Type matches the full varying type (e.g. float3).
  TK_ElemType = 1,     ///< Type is the scalar element type (e.g. float).
  TK_VaryingShape = 2, ///< Type uses the varying shape with a fixed element.
  TK_FixedType = 3,    ///< Type is a fixed concrete type (e.g. "half2").
  TK_Void = 4          ///< Type is void (only valid for return types).
};

/// Metadata describing how a type (argument or return) varies across overloads.
struct TypeInfo {
  /// Classification of how this type varies across overloads.
  TypeKindEnum Kind = TK_Varying;

  /// Fixed type name (e.g. "half2") for types with a concrete type that does
  /// not vary across overloads. Empty for varying types.
  std::string FixedType;

  /// Element type name for TK_VaryingShape types (e.g. "bool" for
  /// VaryingShape<BoolTy>). Empty for other type kinds.
  StringRef ShapeElemType;

  /// Explicit parameter name (e.g. "eta"). Empty to use the default "p0",
  /// "p1", ... naming. Only meaningful for argument types.
  StringRef Name;

  /// Construct a TypeInfo from a TableGen record.
  static TypeInfo resolve(const Record *Rec) {
    TypeInfo TI;
    if (Rec->getName() == "VoidTy") {
      TI.Kind = TK_Void;
    } else if (Rec->getName() == "Varying") {
      TI.Kind = TK_Varying;
    } else if (Rec->getName() == "VaryingElemType") {
      TI.Kind = TK_ElemType;
    } else if (Rec->isSubClassOf("VaryingShape")) {
      TI.Kind = TK_VaryingShape;
      TI.ShapeElemType =
          Rec->getValueAsDef("ElementType")->getValueAsString("Name");
    } else if (Rec->isSubClassOf("VectorType") ||
               Rec->isSubClassOf("HLSLType")) {
      TI.Kind = TK_FixedType;
      TI.FixedType = getFixedTypeName(Rec);
    } else {
      llvm_unreachable("unhandled record for type resolution");
    }
    return TI;
  }

  /// Resolve this type to a concrete type name string.
  /// \p ElemType is the scalar element type for the current overload.
  /// \p FormatVarying formats a scalar element type into the shaped type name.
  std::string
  toTypeString(StringRef ElemType,
               function_ref<std::string(StringRef)> FormatVarying) const {
    switch (Kind) {
    case TK_Void:
      return "void";
    case TK_Varying:
      return FormatVarying(ElemType);
    case TK_ElemType:
      return ElemType.str();
    case TK_VaryingShape:
      return FormatVarying(ShapeElemType);
    case TK_FixedType:
      assert(!FixedType.empty() && "TK_FixedType requires non-empty FixedType");
      return FixedType;
    }
    llvm_unreachable("unhandled TypeKindEnum");
  }
};

} // anonymous namespace

//===----------------------------------------------------------------------===//
// Availability helpers
//===----------------------------------------------------------------------===//

static void emitAvailability(raw_ostream &OS, StringRef Version,
                             bool Use16Bit = false) {
  if (Use16Bit) {
    OS << "_HLSL_16BIT_AVAILABILITY(shadermodel, " << SM6_2;
    if (!Version.empty())
      OS << ", " << Version;
    OS << ")\n";
  } else
    OS << "_HLSL_AVAILABILITY(shadermodel, " << Version << ")\n";
}

static std::string getVersionString(const Record *SM) {
  unsigned Major = SM->getValueAsInt("Major");
  unsigned Minor = SM->getValueAsInt("Minor");
  if (Major == 0 && Minor == 0)
    return "";
  return (Twine(Major) + "." + Twine(Minor)).str();
}

//===----------------------------------------------------------------------===//
// Type work item — describes one element type to emit overloads for
//===----------------------------------------------------------------------===//

namespace {

/// A single entry in the worklist of types to process for an intrinsic.
struct TypeWorkItem {
  /// Element type name (e.g. "half", "float"). Empty for fixed-arg-only
  /// intrinsics with no type expansion.
  StringRef ElemType;

  /// Version string for the availability attribute (e.g. "6.2"). Empty if
  /// no availability annotation is needed.
  std::string Availability;

  /// If true, emit _HLSL_16BIT_AVAILABILITY instead of _HLSL_AVAILABILITY.
  bool Use16BitAvail = false;

  /// If true, wrap overloads in #ifdef __HLSL_ENABLE_16_BIT / #endif.
  bool NeedsIfdefGuard = false;
};

} // anonymous namespace

/// Fixed canonical ordering for overload types. Types are grouped as:
///   0: conditionally-16-bit (half)
///   1-2: 16-bit integers (int16_t, uint16_t) — ifdef-guarded
///   3+: regular types (bool, int, uint, int64_t, uint64_t, float, double)
/// Within each group, signed precedes unsigned, smaller precedes larger,
/// and integer types precede floating-point types.
static int getTypeSortPriority(const Record *ET) {
  return StringSwitch<int>(ET->getValueAsString("Name"))
      .Case("half", 0)
      .Case("int16_t", 1)
      .Case("uint16_t", 2)
      .Case("bool", 3)
      .Case("int", 4)
      .Case("uint", 5)
      .Case("int64_t", 7)
      .Case("uint64_t", 8)
      .Case("float", 9)
      .Case("double", 10)
      .Default(11);
}

//===----------------------------------------------------------------------===//
// Overload context — shared state across all overloads of one intrinsic
//===----------------------------------------------------------------------===//

namespace {

/// Shared state for emitting all overloads of a single HLSL intrinsic.
struct OverloadContext {
  /// Output stream to write generated code to.
  raw_ostream &OS;

  /// Builtin name for _HLSL_BUILTIN_ALIAS (e.g. "__builtin_hlsl_dot").
  /// Empty for inline/detail intrinsics.
  StringRef Builtin;

  /// __detail helper function to call (e.g. "refract_impl").
  /// Empty for alias and inline-body intrinsics.
  StringRef DetailFunc;

  /// Literal inline function body (e.g. "return p0;").
  /// Empty for alias and detail intrinsics.
  StringRef Body;

  /// The HLSL function name to emit (e.g. "dot", "refract").
  StringRef FuncName;

  /// Metadata describing the return type and its variation behavior.
  TypeInfo RetType;

  /// Per-argument metadata describing type and variation behavior.
  SmallVector<TypeInfo, 4> Args;

  /// Whether to emit the function as constexpr.
  bool IsConstexpr = false;

  /// Whether to emit the __attribute__((convergent)) annotation.
  bool IsConvergent = false;

  /// Whether any fixed arg has a 16-bit integer type (e.g. int16_t).
  bool Uses16BitType = false;

  /// Whether any fixed arg has a conditionally-16-bit type (half).
  bool UsesConditionally16BitType = false;

  explicit OverloadContext(raw_ostream &OS) : OS(OS) {}
};

} // anonymous namespace

/// Emit a complete function declaration or definition with pre-resolved types.
static void emitDeclaration(const OverloadContext &Ctx, StringRef RetType,
                            ArrayRef<std::string> ArgTypes) {
  raw_ostream &OS = Ctx.OS;
  bool IsDetail = !Ctx.DetailFunc.empty();
  bool IsInline = !Ctx.Body.empty();
  bool HasBody = IsDetail || IsInline;

  bool EmitNames = HasBody || llvm::any_of(Ctx.Args, [](const TypeInfo &A) {
                     return !A.Name.empty();
                   });

  auto GetParamName = [&](unsigned I) -> std::string {
    if (!Ctx.Args[I].Name.empty())
      return Ctx.Args[I].Name.str();
    return ("p" + Twine(I)).str();
  };

  if (!HasBody)
    OS << "_HLSL_BUILTIN_ALIAS(" << Ctx.Builtin << ")\n";
  if (Ctx.IsConvergent)
    OS << "__attribute__((convergent)) ";
  if (HasBody)
    OS << (Ctx.IsConstexpr ? "constexpr " : "inline ");
  OS << RetType << " " << Ctx.FuncName << "(";

  {
    ListSeparator LS;
    for (unsigned I = 0, N = ArgTypes.size(); I < N; ++I) {
      OS << LS << ArgTypes[I];
      if (EmitNames)
        OS << " " << GetParamName(I);
    }
  }

  if (IsDetail) {
    OS << ") {\n  return __detail::" << Ctx.DetailFunc << "(";
    ListSeparator LS;
    for (unsigned I = 0, N = ArgTypes.size(); I < N; ++I)
      OS << LS << GetParamName(I);
    OS << ");\n}\n";
  } else if (IsInline) {
    OS << ") { " << Ctx.Body << " }\n";
  } else {
    OS << ");\n";
  }
}

/// Emit a single overload declaration by resolving all types through
/// \p FormatVarying, which maps element types to their shaped form.
static void emitOverload(const OverloadContext &Ctx, StringRef ElemType,
                         function_ref<std::string(StringRef)> FormatVarying) {
  std::string RetType = Ctx.RetType.toTypeString(ElemType, FormatVarying);
  SmallVector<std::string> ArgTypes;
  for (const TypeInfo &TI : Ctx.Args)
    ArgTypes.push_back(TI.toTypeString(ElemType, FormatVarying));
  emitDeclaration(Ctx, RetType, ArgTypes);
}

/// Emit a scalar overload for the given element type.
static void emitScalarOverload(const OverloadContext &Ctx, StringRef ElemType) {
  emitOverload(Ctx, ElemType, [](StringRef ET) { return ET.str(); });
}

/// Emit a vector overload for the given element type and vector size.
static void emitVectorOverload(const OverloadContext &Ctx, StringRef ElemType,
                               unsigned VecSize) {
  emitOverload(Ctx, ElemType, [VecSize](StringRef ET) {
    return getVectorTypeName(ET, VecSize);
  });
}

/// Emit a dependent-size vector template overload for the given element type.
static void emitLongVectorOverload(const OverloadContext &Ctx,
                                   StringRef ElemType) {
  emitOverload(Ctx, ElemType, [](StringRef ET) {
    return ("vector<__detail::enable_if_t<(N > 4), " + ET + ">, N>").str();
  });
}

/// Emit a matrix overload for the given element type and matrix dimensions.
static void emitMatrixOverload(const OverloadContext &Ctx, StringRef ElemType,
                               unsigned Rows, unsigned Cols) {
  emitOverload(Ctx, ElemType, [Rows, Cols](StringRef ET) {
    return getMatrixTypeName(ET, Rows, Cols);
  });
}

//===----------------------------------------------------------------------===//
// Main emission logic
//===----------------------------------------------------------------------===//

/// Build an OverloadContext from an HLSLBuiltin record.
static void buildOverloadContext(const Record *R, OverloadContext &Ctx) {
  Ctx.Builtin = R->getValueAsString("Builtin");
  Ctx.DetailFunc = R->getValueAsString("DetailFunc");
  Ctx.Body = R->getValueAsString("Body");
  Ctx.FuncName = R->getValueAsString("Name");
  Ctx.IsConstexpr = R->getValueAsBit("IsConstexpr");
  Ctx.IsConvergent = R->getValueAsBit("IsConvergent");

  // Note use of 16-bit fixed types in the overload context.
  auto Update16BitFlags = [&Ctx](const Record *Rec) {
    const Record *ElemTy = getElementTypeRecord(Rec);
    Ctx.Uses16BitType |= ElemTy->getValueAsBit("Is16Bit");
    Ctx.UsesConditionally16BitType |=
        ElemTy->getValueAsBit("IsConditionally16Bit");
  };

  // Resolve return and argument types.
  const Record *RetRec = R->getValueAsDef("ReturnType");
  Ctx.RetType = TypeInfo::resolve(RetRec);
  if (Ctx.RetType.Kind == TK_FixedType)
    Update16BitFlags(RetRec);

  std::vector<const Record *> ArgRecords = R->getValueAsListOfDefs("Args");
  std::vector<StringRef> ParamNames = R->getValueAsListOfStrings("ParamNames");

  for (const auto &[I, Arg] : llvm::enumerate(ArgRecords)) {
    TypeInfo TI = TypeInfo::resolve(Arg);
    if (I < ParamNames.size())
      TI.Name = ParamNames[I];
    if (TI.Kind == TK_FixedType)
      Update16BitFlags(Arg);
    Ctx.Args.push_back(TI);
  }
}

/// Build the worklist of element types to emit overloads for, sorted in
/// canonical order (see getTypeSortPriority).
static void buildWorklist(const Record *R,
                          SmallVectorImpl<TypeWorkItem> &Worklist,
                          const OverloadContext &Ctx) {
  const Record *AvailRec = R->getValueAsDef("Availability");
  std::string Availability = getVersionString(AvailRec);
  bool AvailabilityIsAtLeastSM6_2 = AvailRec->getValueAsInt("Major") > 6 ||
                                    (AvailRec->getValueAsInt("Major") == 6 &&
                                     AvailRec->getValueAsInt("Minor") >= 2);

  std::vector<const Record *> VaryingTypeRecords =
      R->getValueAsListOfDefs("VaryingTypes");

  // Populate the availability and guard fields of a TypeWorkItem based on
  // whether the type is 16-bit, conditionally 16-bit, or a regular type.
  auto SetAvailability = [&](TypeWorkItem &Item, bool Is16Bit,
                             bool IsCond16Bit) {
    Item.NeedsIfdefGuard = Is16Bit;
    if (Is16Bit || IsCond16Bit) {
      if (AvailabilityIsAtLeastSM6_2) {
        Item.Availability = Availability;
      } else {
        Item.Use16BitAvail = IsCond16Bit;
        if (IsCond16Bit)
          Item.Availability = Availability;
        else
          Item.Availability = SM6_2;
      }
    } else {
      Item.Availability = Availability;
    }
  };

  // If no Varying types are specified, just add a single work item.
  // This is for HLSLBuiltin records that don't use Varying types.
  if (VaryingTypeRecords.empty()) {
    TypeWorkItem Item;
    SetAvailability(Item, Ctx.Uses16BitType, Ctx.UsesConditionally16BitType);
    Worklist.push_back(Item);
    return;
  }

  // Sort Varying types so that overloads are always emitted in canonical order.
  llvm::sort(VaryingTypeRecords, [](const Record *A, const Record *B) {
    return getTypeSortPriority(A) < getTypeSortPriority(B);
  });

  // Add a work item for each Varying element type.
  for (const Record *ElemTy : VaryingTypeRecords) {
    TypeWorkItem Item;
    Item.ElemType = ElemTy->getValueAsString("Name");
    bool Is16Bit = Ctx.Uses16BitType || ElemTy->getValueAsBit("Is16Bit");
    bool IsCond16Bit = Ctx.UsesConditionally16BitType ||
                       ElemTy->getValueAsBit("IsConditionally16Bit");
    SetAvailability(Item, Is16Bit, IsCond16Bit);
    Worklist.push_back(Item);
  }
}

/// Emit a Doxygen documentation comment from the Doc field.
static void emitDocComment(raw_ostream &OS, const Record *R) {
  StringRef Doc = R->getValueAsString("Doc");
  if (Doc.empty())
    return;
  Doc = Doc.trim();
  SmallVector<StringRef> DocLines;
  Doc.split(DocLines, '\n');
  for (StringRef Line : DocLines) {
    if (Line.empty())
      OS << "///\n";
    else
      OS << "/// " << Line << "\n";
  }
}

/// Process the worklist: emit all shape variants for each type with
/// availability annotations and #ifdef guards.
static void emitWorklistOverloads(raw_ostream &OS, const OverloadContext &Ctx,
                                  ArrayRef<TypeWorkItem> Worklist,
                                  bool EmitScalarOverload,
                                  ArrayRef<int64_t> VectorSizes,
                                  bool EmitLongVectorOverload,
                                  ArrayRef<const Record *> MatrixDimensions) {
  bool InIfdef = false;
  for (size_t I = 0, E = Worklist.size(); I != E; ++I) {
    const TypeWorkItem &Item = Worklist[I];
    if (Item.NeedsIfdefGuard && !InIfdef) {
      OS << "#ifdef __HLSL_ENABLE_16_BIT\n";
      InIfdef = true;
    }

    auto EmitAvail = [&]() {
      if (!Item.Availability.empty() || Item.Use16BitAvail)
        emitAvailability(OS, Item.Availability, Item.Use16BitAvail);
    };

    if (EmitScalarOverload) {
      EmitAvail();
      emitScalarOverload(Ctx, Item.ElemType);
    }
    for (int64_t N : VectorSizes) {
      EmitAvail();
      emitVectorOverload(Ctx, Item.ElemType, N);
    }
    if (EmitLongVectorOverload) {
      OS << "template <int N>\n";
      EmitAvail();
      emitLongVectorOverload(Ctx, Item.ElemType);
    }
    for (const Record *MD : MatrixDimensions) {
      EmitAvail();
      emitMatrixOverload(Ctx, Item.ElemType, MD->getValueAsInt("Rows"),
                         MD->getValueAsInt("Cols"));
    }

    if (InIfdef) {
      bool NextIsUnguarded = (I + 1 == E) || !Worklist[I + 1].NeedsIfdefGuard;
      if (NextIsUnguarded) {
        OS << "#endif\n";
        InIfdef = false;
      }
    }

    OS << "\n";
  }
}

/// Emit all overloads for a single HLSLBuiltin record.
static void emitBuiltinOverloads(raw_ostream &OS, const Record *R) {
  OverloadContext Ctx(OS);
  buildOverloadContext(R, Ctx);

  SmallVector<TypeWorkItem> Worklist;
  buildWorklist(R, Worklist, Ctx);

  emitDocComment(OS, R);
  OS << "// " << Ctx.FuncName << " overloads\n";

  // Emit a scalar overload if a scalar Varying overload was requested.
  // If no Varying types are used at all, emit a scalar overload to handle
  // emitting a single overload for fixed-typed args or arg-less functions.
  bool EmitScalarOverload = R->getValueAsBit("VaryingScalar") ||
                            R->getValueAsListOfDefs("VaryingTypes").empty();

  std::vector<int64_t> VectorSizes = R->getValueAsListOfInts("VaryingVecSizes");
  bool EmitLongVectorOverload = R->getValueAsBit("VaryingLongVector");
  std::vector<const Record *> MatrixDimensions =
      R->getValueAsListOfDefs("VaryingMatDims");

  // Sort vector sizes and matrix dimensions for consistent output order.
  llvm::sort(VectorSizes);
  llvm::sort(MatrixDimensions, [](const Record *A, const Record *B) {
    int RowA = A->getValueAsInt("Rows"), RowB = B->getValueAsInt("Rows");
    if (RowA != RowB)
      return RowA < RowB;
    return A->getValueAsInt("Cols") < B->getValueAsInt("Cols");
  });

  emitWorklistOverloads(OS, Ctx, Worklist, EmitScalarOverload, VectorSizes,
                        EmitLongVectorOverload, MatrixDimensions);
}

/// Emit alias overloads for a single HLSLBuiltin record.
/// Skips records that have inline bodies (DetailFunc or Body).
static void emitAliasBuiltin(raw_ostream &OS, const Record *R) {
  if (!R->getValueAsString("DetailFunc").empty() ||
      !R->getValueAsString("Body").empty())
    return;
  emitBuiltinOverloads(OS, R);
}

/// Emit inline overloads for a single HLSLBuiltin record.
/// Skips records that are pure alias declarations.
static void emitInlineBuiltin(raw_ostream &OS, const Record *R) {
  if (R->getValueAsString("DetailFunc").empty() &&
      R->getValueAsString("Body").empty())
    return;
  emitBuiltinOverloads(OS, R);
}

void clang::EmitHLSLAliasIntrinsics(const RecordKeeper &Records,
                                    raw_ostream &OS) {
  OS << "// This file is auto-generated by clang-tblgen from "
        "HLSLIntrinsics.td.\n";
  OS << "// Do not edit this file directly.\n\n";

  for (const Record *R : Records.getAllDerivedDefinitions("HLSLBuiltin"))
    emitAliasBuiltin(OS, R);
}

void clang::EmitHLSLInlineIntrinsics(const RecordKeeper &Records,
                                     raw_ostream &OS) {
  OS << "// This file is auto-generated by clang-tblgen from "
        "HLSLIntrinsics.td.\n";
  OS << "// Do not edit this file directly.\n\n";

  for (const Record *R : Records.getAllDerivedDefinitions("HLSLBuiltin"))
    emitInlineBuiltin(OS, R);
}
