================
@@ -0,0 +1,586 @@
+//===--- HLSLEmitter.cpp - HLSL intrinsic header generator 
----------------===//
+//
+// 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 "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.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;
+
+namespace {
+
+/// Minimum shader model version that supports 16-bit types.
+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
+//===----------------------------------------------------------------------===//
+
+/// 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");
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Availability helpers
+//===----------------------------------------------------------------------===//
+
+static void emitAvailability(raw_ostream &OS, StringRef Version,
+                             bool Use16Bit = false) {
+  if (Use16Bit) {
+    OS << "_HLSL_16BIT_AVAILABILITY(shadermodel, " << Version << ")\n";
+  } else {
+    OS << "_HLSL_AVAILABILITY(shadermodel, " << Version << ")\n";
+  }
+}
+static std::string getVersionString(const Record *SM) {
----------------
jurahul wrote:

nit: can you add an empty line between functions?

https://github.com/llvm/llvm-project/pull/187610
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to