From 9259b071be57d5c0612da68dd9fa37479fabc4aa Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Thu, 15 Aug 2024 00:28:10 +0300 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5-bogner [skip ci] --- llvm/docs/DirectX/DXILOpTableGenDesign.rst | 28 +- llvm/include/llvm/Support/DXILABI.h | 17 -- llvm/lib/Target/DirectX/DXIL.td | 255 +++++++++--------- llvm/lib/Target/DirectX/DXILConstants.h | 5 + llvm/lib/Target/DirectX/DXILOpBuilder.cpp | 88 +++--- llvm/lib/Target/DirectX/DXILOpBuilder.h | 23 +- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 128 +++++---- llvm/lib/Target/DirectX/DXILOpLowering.h | 27 ++ llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp | 42 +-- llvm/lib/Target/DirectX/DXILPrettyPrinter.h | 33 +++ .../lib/Target/DirectX/DXILResourceAnalysis.h | 4 + .../Target/DirectX/DXILTranslateMetadata.cpp | 78 +++--- .../Target/DirectX/DXILTranslateMetadata.h | 24 ++ llvm/lib/Target/DirectX/DirectX.h | 8 +- .../Target/DirectX/DirectXPassRegistry.def | 5 +- .../Target/DirectX/DirectXTargetMachine.cpp | 10 +- .../DXILResource/buffer-frombinding.ll | 6 +- .../CodeGen/DirectX/Metadata/dxilVer-1.0.ll | 2 +- .../CodeGen/DirectX/Metadata/dxilVer-1.8.ll | 2 +- .../DirectX/Metadata/shaderModel-as.ll | 2 +- .../DirectX/Metadata/shaderModel-cs.ll | 2 +- .../DirectX/Metadata/shaderModel-gs.ll | 2 +- .../DirectX/Metadata/shaderModel-hs.ll | 2 +- .../DirectX/Metadata/shaderModel-lib.ll | 2 +- .../DirectX/Metadata/shaderModel-ms.ll | 2 +- .../DirectX/Metadata/shaderModel-ps.ll | 3 +- .../DirectX/Metadata/shaderModel-vs.ll | 2 +- llvm/test/CodeGen/DirectX/UAVMetadata.ll | 4 +- llvm/test/CodeGen/DirectX/any.ll | 2 +- llvm/test/CodeGen/DirectX/cbuf.ll | 4 +- llvm/test/CodeGen/DirectX/dxil_ver.ll | 2 +- llvm/test/CodeGen/DirectX/floor.ll | 2 +- .../CodeGen/DirectX/legacy_cb_layout_0.ll | 2 +- .../CodeGen/DirectX/legacy_cb_layout_1.ll | 2 +- .../CodeGen/DirectX/legacy_cb_layout_2.ll | 2 +- .../CodeGen/DirectX/legacy_cb_layout_3.ll | 2 +- llvm/test/CodeGen/DirectX/lib_entry.ll | 2 +- llvm/test/Frontend/HLSL/empty_cs_entry.ll | 2 +- llvm/utils/TableGen/DXILEmitter.cpp | 176 ++++-------- 39 files changed, 515 insertions(+), 489 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILOpLowering.h create mode 100644 llvm/lib/Target/DirectX/DXILPrettyPrinter.h create mode 100644 llvm/lib/Target/DirectX/DXILTranslateMetadata.h diff --git a/llvm/docs/DirectX/DXILOpTableGenDesign.rst b/llvm/docs/DirectX/DXILOpTableGenDesign.rst index 50d801bd05efd..46106ee2a50f5 100644 --- a/llvm/docs/DirectX/DXILOpTableGenDesign.rst +++ b/llvm/docs/DirectX/DXILOpTableGenDesign.rst @@ -93,18 +93,14 @@ properties are specified as fields of the ``DXILOp`` class as described below. class DXILOpClass; Concrete operation records, such as ``unary`` are defined by inheriting from ``DXILOpClass``. -6. Return type of the operation is represented as ``LLVMType``. -7. Operation arguments are represented as a list of ``LLVMType`` with each type - corresponding to the argument position. An overload type, if supported by the operation, is - denoted as the positional type ``overloadTy`` in the argument or in the result, where - ``overloadTy`` is defined to be synonymous to ``llvm_any_ty``. - - .. code-block:: - - defvar overloadTy = llvm_any_ty - - Empty list, ``[]`` represents an operation with no arguments. - +6. A set of type names are defined that represent return and argument types, + which all inherit from ``DXILOpParamType``. These represent simple types + like ``int32Ty``, DXIL types like ``dx.types.Handle``, and a special + ``overloadTy`` which can be any type allowed by ``Overloads``, described + below. +7. Operation return type is represented as a ``DXILOpParamType``, and arguments + are represented as a list of the same. An operation with no return value + shall specify ``VoidTy`` as its return. 8. Valid operation overload types predicated on DXIL version are specified as a list of ``Overloads`` records. Representation of ``Overloads`` class is described in a later section. @@ -145,10 +141,10 @@ TableGen representations of its properties described above. Intrinsic LLVMIntrinsic = ?; // Result type of the op. - LLVMType result; + DXILOpParamType result; // List of argument types of the op. Default to 0 arguments. - list arguments = []; + list arguments = []; // List of valid overload types predicated by DXIL version list overloads; @@ -233,9 +229,9 @@ overloads predicated on DXIL version as list of records of the following class .. code-block:: - class Overloads ols> { + class Overloads ols> { Version dxil_version = minver; - list overload_types = ols; + list overload_types = ols; } Following is an example specification of valid overload types for ``DXIL1_0`` and diff --git a/llvm/include/llvm/Support/DXILABI.h b/llvm/include/llvm/Support/DXILABI.h index a2222eec09ba8..cf2c42c689889 100644 --- a/llvm/include/llvm/Support/DXILABI.h +++ b/llvm/include/llvm/Support/DXILABI.h @@ -22,23 +22,6 @@ namespace llvm { namespace dxil { -enum class ParameterKind : uint8_t { - Invalid = 0, - Void, - Half, - Float, - Double, - I1, - I8, - I16, - I32, - I64, - Overload, - CBufferRet, - ResourceRet, - DXILHandle, -}; - enum class ResourceClass : uint8_t { SRV = 0, UAV, diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 67015cff78a79..34c7f84b1ca5b 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -24,19 +24,24 @@ foreach i = 0...8 in { def DXIL1_ #i : Version<1, i>; } -// Overload type alias of llvm_any_ty -defvar overloadTy = llvm_any_ty; - -// Type aliases for DXIL Op types to LLVM Types. -// TODO: Define DXIL Types independent of LLVM types -defvar i1Ty = llvm_i1_ty; -defvar i8Ty = llvm_i8_ty; -defvar i16Ty = llvm_i16_ty; -defvar i32Ty = llvm_i32_ty; -defvar i64Ty = llvm_i64_ty; -defvar halfTy = llvm_half_ty; -defvar floatTy = llvm_float_ty; -defvar doubleTy = llvm_double_ty; +class DXILOpParamType { + int isOverload = 0; +} + +let isOverload = 1 in { + def OverloadTy : DXILOpParamType; +} +def VoidTy : DXILOpParamType; +def Int1Ty : DXILOpParamType; +def Int8Ty : DXILOpParamType; +def Int16Ty : DXILOpParamType; +def Int32Ty : DXILOpParamType; +def Int64Ty : DXILOpParamType; +def HalfTy : DXILOpParamType; +def FloatTy : DXILOpParamType; +def DoubleTy : DXILOpParamType; +def ResRetTy : DXILOpParamType; +def HandleTy : DXILOpParamType; class DXILOpClass; @@ -268,9 +273,9 @@ def IsWave : DXILAttribute; def NeedsUniformInputs : DXILAttribute; def IsBarrier : DXILAttribute; -class Overloads ols> { +class Overloads ols> { Version dxil_version = ver; - list overload_types = ols; + list overload_types = ols; } class Stages st> { @@ -298,10 +303,10 @@ class DXILOp { Intrinsic LLVMIntrinsic = ?; // Result type of the op - LLVMType result; + DXILOpParamType result; // List of argument types of the op. Default to 0 arguments. - list arguments = []; + list arguments = []; // List of valid overload types predicated by DXIL version list overloads = []; @@ -318,9 +323,9 @@ class DXILOp { def Abs : DXILOp<6, unary> { let Doc = "Returns the absolute value of the input."; let LLVMIntrinsic = int_fabs; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -328,9 +333,9 @@ def Abs : DXILOp<6, unary> { def IsInf : DXILOp<9, isSpecialFloat> { let Doc = "Determines if the specified value is infinite."; let LLVMIntrinsic = int_dx_isinf; - let arguments = [overloadTy]; - let result = i1Ty; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = Int1Ty; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -338,9 +343,9 @@ def IsInf : DXILOp<9, isSpecialFloat> { def Cos : DXILOp<12, unary> { let Doc = "Returns cosine(theta) for theta in radians."; let LLVMIntrinsic = int_cos; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -348,9 +353,9 @@ def Cos : DXILOp<12, unary> { def Sin : DXILOp<13, unary> { let Doc = "Returns sine(theta) for theta in radians."; let LLVMIntrinsic = int_sin; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -358,9 +363,9 @@ def Sin : DXILOp<13, unary> { def Tan : DXILOp<14, unary> { let Doc = "Returns tangent(theta) for theta in radians."; let LLVMIntrinsic = int_tan; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -368,9 +373,9 @@ def Tan : DXILOp<14, unary> { def ACos : DXILOp<15, unary> { let Doc = "Returns the arccosine of the specified value."; let LLVMIntrinsic = int_acos; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -378,9 +383,9 @@ def ACos : DXILOp<15, unary> { def ASin : DXILOp<16, unary> { let Doc = "Returns the arcsine of the specified value."; let LLVMIntrinsic = int_asin; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -388,9 +393,9 @@ def ASin : DXILOp<16, unary> { def ATan : DXILOp<17, unary> { let Doc = "Returns the arctangent of the specified value."; let LLVMIntrinsic = int_atan; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -398,9 +403,9 @@ def ATan : DXILOp<17, unary> { def HCos : DXILOp<18, unary> { let Doc = "Returns the hyperbolic cosine of the specified value."; let LLVMIntrinsic = int_cosh; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -408,9 +413,9 @@ def HCos : DXILOp<18, unary> { def HSin : DXILOp<19, unary> { let Doc = "Returns the hyperbolic sine of the specified value."; let LLVMIntrinsic = int_sinh; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -418,9 +423,9 @@ def HSin : DXILOp<19, unary> { def HTan : DXILOp<20, unary> { let Doc = "Returns the hyperbolic tan of the specified value."; let LLVMIntrinsic = int_tanh; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -429,9 +434,9 @@ def Exp2 : DXILOp<21, unary> { let Doc = "Returns the base 2 exponential, or 2**x, of the specified value. " "exp2(x) = 2**x."; let LLVMIntrinsic = int_exp2; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -440,9 +445,9 @@ def Frac : DXILOp<22, unary> { let Doc = "Returns a fraction from 0 to 1 that represents the decimal part " "of the input."; let LLVMIntrinsic = int_dx_frac; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -450,9 +455,9 @@ def Frac : DXILOp<22, unary> { def Log2 : DXILOp<23, unary> { let Doc = "Returns the base-2 logarithm of the specified value."; let LLVMIntrinsic = int_log2; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -461,9 +466,9 @@ def Sqrt : DXILOp<24, unary> { let Doc = "Returns the square root of the specified floating-point value, " "per component."; let LLVMIntrinsic = int_sqrt; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -472,9 +477,9 @@ def RSqrt : DXILOp<25, unary> { let Doc = "Returns the reciprocal of the square root of the specified value. " "rsqrt(x) = 1 / sqrt(x)."; let LLVMIntrinsic = int_dx_rsqrt; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -483,9 +488,9 @@ def Round : DXILOp<26, unary> { let Doc = "Returns the input rounded to the nearest integer within a " "floating-point type."; let LLVMIntrinsic = int_roundeven; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -494,9 +499,9 @@ def Floor : DXILOp<27, unary> { let Doc = "Returns the largest integer that is less than or equal to the input."; let LLVMIntrinsic = int_floor; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -505,9 +510,9 @@ def Ceil : DXILOp<28, unary> { let Doc = "Returns the smallest integer that is greater than or equal to the " "input."; let LLVMIntrinsic = int_ceil; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -515,9 +520,9 @@ def Ceil : DXILOp<28, unary> { def Trunc : DXILOp<29, unary> { let Doc = "Returns the specified value truncated to the integer component."; let LLVMIntrinsic = int_trunc; - let arguments = [overloadTy]; - let result = overloadTy; - let overloads = [Overloads]; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -525,10 +530,10 @@ def Trunc : DXILOp<29, unary> { def Rbits : DXILOp<30, unary> { let Doc = "Returns the specified value with its bits reversed."; let LLVMIntrinsic = int_bitreverse; - let arguments = [overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -536,10 +541,10 @@ def Rbits : DXILOp<30, unary> { def FMax : DXILOp<35, binary> { let Doc = "Float maximum. FMax(a,b) = a > b ? a : b"; let LLVMIntrinsic = int_maxnum; - let arguments = [overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -547,10 +552,10 @@ def FMax : DXILOp<35, binary> { def FMin : DXILOp<36, binary> { let Doc = "Float minimum. FMin(a,b) = a < b ? a : b"; let LLVMIntrinsic = int_minnum; - let arguments = [overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -558,10 +563,10 @@ def FMin : DXILOp<36, binary> { def SMax : DXILOp<37, binary> { let Doc = "Signed integer maximum. SMax(a,b) = a > b ? a : b"; let LLVMIntrinsic = int_smax; - let arguments = [overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -569,10 +574,10 @@ def SMax : DXILOp<37, binary> { def SMin : DXILOp<38, binary> { let Doc = "Signed integer minimum. SMin(a,b) = a < b ? a : b"; let LLVMIntrinsic = int_smin; - let arguments = [overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -580,10 +585,10 @@ def SMin : DXILOp<38, binary> { def UMax : DXILOp<39, binary> { let Doc = "Unsigned integer maximum. UMax(a,b) = a > b ? a : b"; let LLVMIntrinsic = int_umax; - let arguments = [overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -591,10 +596,10 @@ def UMax : DXILOp<39, binary> { def UMin : DXILOp<40, binary> { let Doc = "Unsigned integer minimum. UMin(a,b) = a < b ? a : b"; let LLVMIntrinsic = int_umin; - let arguments = [overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -603,10 +608,10 @@ def FMad : DXILOp<46, tertiary> { let Doc = "Floating point arithmetic multiply/add operation. fmad(m,a,b) = m " "* a + b."; let LLVMIntrinsic = int_fmuladd; - let arguments = [overloadTy, overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -615,10 +620,10 @@ def IMad : DXILOp<48, tertiary> { let Doc = "Signed integer arithmetic multiply/add operation. imad(m,a,b) = m " "* a + b."; let LLVMIntrinsic = int_dx_imad; - let arguments = [overloadTy, overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -627,10 +632,10 @@ def UMad : DXILOp<49, tertiary> { let Doc = "Unsigned integer arithmetic multiply/add operation. umad(m,a, = m " "* a + b."; let LLVMIntrinsic = int_dx_umad; - let arguments = [overloadTy, overloadTy, overloadTy]; - let result = overloadTy; + let arguments = [OverloadTy, OverloadTy, OverloadTy]; + let result = OverloadTy; let overloads = - [Overloads]; + [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -639,9 +644,9 @@ def Dot2 : DXILOp<54, dot2> { let Doc = "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + " "a[n]*b[n] where n is between 0 and 1"; let LLVMIntrinsic = int_dx_dot2; - let arguments = !listsplat(overloadTy, 4); - let result = overloadTy; - let overloads = [Overloads]; + let arguments = !listsplat(OverloadTy, 4); + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -650,9 +655,9 @@ def Dot3 : DXILOp<55, dot3> { let Doc = "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + " "a[n]*b[n] where n is between 0 and 2"; let LLVMIntrinsic = int_dx_dot3; - let arguments = !listsplat(overloadTy, 6); - let result = overloadTy; - let overloads = [Overloads]; + let arguments = !listsplat(OverloadTy, 6); + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -661,9 +666,9 @@ def Dot4 : DXILOp<56, dot4> { let Doc = "dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + " "a[n]*b[n] where n is between 0 and 3"; let LLVMIntrinsic = int_dx_dot4; - let arguments = !listsplat(overloadTy, 8); - let result = overloadTy; - let overloads = [Overloads]; + let arguments = !listsplat(OverloadTy, 8); + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -671,8 +676,9 @@ def Dot4 : DXILOp<56, dot4> { def ThreadId : DXILOp<93, threadId> { let Doc = "Reads the thread ID"; let LLVMIntrinsic = int_dx_thread_id; - let arguments = [i32Ty]; - let result = i32Ty; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -680,8 +686,9 @@ def ThreadId : DXILOp<93, threadId> { def GroupId : DXILOp<94, groupId> { let Doc = "Reads the group ID (SV_GroupID)"; let LLVMIntrinsic = int_dx_group_id; - let arguments = [i32Ty]; - let result = i32Ty; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -689,8 +696,9 @@ def GroupId : DXILOp<94, groupId> { def ThreadIdInGroup : DXILOp<95, threadIdInGroup> { let Doc = "Reads the thread ID within the group (SV_GroupThreadID)"; let LLVMIntrinsic = int_dx_thread_id_in_group; - let arguments = [i32Ty]; - let result = i32Ty; + let arguments = [OverloadTy]; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } @@ -699,7 +707,8 @@ def FlattenedThreadIdInGroup : DXILOp<96, flattenedThreadIdInGroup> { let Doc = "Provides a flattened index for a given thread within a given " "group (SV_GroupIndex)"; let LLVMIntrinsic = int_dx_flattened_thread_id_in_group; - let result = i32Ty; + let result = OverloadTy; + let overloads = [Overloads]; let stages = [Stages]; let attributes = [Attributes]; } diff --git a/llvm/lib/Target/DirectX/DXILConstants.h b/llvm/lib/Target/DirectX/DXILConstants.h index 0c9c1ac38fdbc..022cd57795a06 100644 --- a/llvm/lib/Target/DirectX/DXILConstants.h +++ b/llvm/lib/Target/DirectX/DXILConstants.h @@ -25,6 +25,11 @@ enum class OpCodeClass : unsigned { #include "DXILOperation.inc" }; +enum class OpParamType : unsigned { +#define DXIL_OP_PARAM_TYPE(Name) Name, +#include "DXILOperation.inc" +}; + } // namespace dxil } // namespace llvm diff --git a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp index 42df7c90cb337..7d2b40cc515cc 100644 --- a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp +++ b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp @@ -11,7 +11,6 @@ #include "DXILOpBuilder.h" #include "DXILConstants.h" -#include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "llvm/Support/DXILABI.h" #include "llvm/Support/ErrorHandling.h" @@ -87,6 +86,9 @@ static const char *getOverloadTypeName(OverloadKind Kind) { } static OverloadKind getOverloadKind(Type *Ty) { + if (!Ty) + return OverloadKind::VOID; + Type::TypeID T = Ty->getTypeID(); switch (T) { case Type::VoidTyID: @@ -156,8 +158,6 @@ struct OpCodeProperty { llvm::SmallVector Attributes; 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 @@ -208,35 +208,33 @@ static StructType *getHandleType(LLVMContext &Ctx) { Ctx); } -static Type *getTypeFromParameterKind(ParameterKind Kind, LLVMContext &Ctx, - Type *OverloadTy) { +static Type *getTypeFromOpParamType(OpParamType Kind, LLVMContext &Ctx, + Type *OverloadTy) { switch (Kind) { - case ParameterKind::Void: + case OpParamType::VoidTy: return Type::getVoidTy(Ctx); - case ParameterKind::Half: + case OpParamType::HalfTy: return Type::getHalfTy(Ctx); - case ParameterKind::Float: + case OpParamType::FloatTy: return Type::getFloatTy(Ctx); - case ParameterKind::Double: + case OpParamType::DoubleTy: return Type::getDoubleTy(Ctx); - case ParameterKind::I1: + case OpParamType::Int1Ty: return Type::getInt1Ty(Ctx); - case ParameterKind::I8: + case OpParamType::Int8Ty: return Type::getInt8Ty(Ctx); - case ParameterKind::I16: + case OpParamType::Int16Ty: return Type::getInt16Ty(Ctx); - case ParameterKind::I32: + case OpParamType::Int32Ty: return Type::getInt32Ty(Ctx); - case ParameterKind::I64: + case OpParamType::Int64Ty: return Type::getInt64Ty(Ctx); - case ParameterKind::Overload: + case OpParamType::OverloadTy: return OverloadTy; - case ParameterKind::ResourceRet: + case OpParamType::ResRetTy: return getResRetType(OverloadTy, Ctx); - case ParameterKind::DXILHandle: + case OpParamType::HandleTy: return getHandleType(Ctx); - default: - break; } llvm_unreachable("Invalid parameter kind"); return nullptr; @@ -281,30 +279,34 @@ static ShaderKind getShaderKindEnum(Triple::EnvironmentType EnvType) { "Shader Kind Not Found - Invalid DXIL Environment Specified"); } +static SmallVector +getArgTypesFromOpParamTypes(ArrayRef Types, + LLVMContext &Context, Type *OverloadTy) { + SmallVector ArgTys; + ArgTys.emplace_back(Type::getInt32Ty(Context)); + for (dxil::OpParamType Ty : Types) + ArgTys.emplace_back(getTypeFromOpParamType(Ty, Context, OverloadTy)); + return ArgTys; +} + /// Construct DXIL function type. This is the type of a function with /// the following prototype /// OverloadType dx.op..(int opcode, ) /// are constructed from types in Prop. -static FunctionType *getDXILOpFunctionType(const OpCodeProperty *Prop, +static FunctionType *getDXILOpFunctionType(dxil::OpCode OpCode, LLVMContext &Context, Type *OverloadTy) { - SmallVector ArgTys; - - const ParameterKind *ParamKinds = getOpCodeParameterKind(*Prop); - assert(Prop->NumOfParameters && "No return type?"); - // Add return type of the function - Type *ReturnTy = getTypeFromParameterKind(ParamKinds[0], Context, OverloadTy); - - // Add DXIL Opcode value type viz., Int32 as first argument - ArgTys.emplace_back(Type::getInt32Ty(Context)); - - // Add DXIL Operation parameter types as specified in DXIL properties - for (unsigned I = 1; I < Prop->NumOfParameters; ++I) { - ParameterKind Kind = ParamKinds[I]; - ArgTys.emplace_back(getTypeFromParameterKind(Kind, Context, OverloadTy)); + switch (OpCode) { +#define DXIL_OP_FUNCTION_TYPE(OpCode, RetType, ...) \ + case OpCode: \ + return FunctionType::get( \ + getTypeFromOpParamType(RetType, Context, OverloadTy), \ + getArgTypesFromOpParamTypes({__VA_ARGS__}, Context, OverloadTy), \ + /*isVarArg=*/false); +#include "DXILOperation.inc" } - return FunctionType::get(ReturnTy, ArgTys, /*isVarArg=*/false); + llvm_unreachable("Invalid OpCode?"); } /// Get index of the property from PropList valid for the most recent @@ -332,7 +334,7 @@ namespace dxil { // Triple is well-formed or that the target is supported since these checks // would have been done at the time the module M is constructed in the earlier // stages of compilation. -DXILOpBuilder::DXILOpBuilder(Module &M, IRBuilderBase &B) : M(M), B(B) { +DXILOpBuilder::DXILOpBuilder(Module &M) : M(M), IRB(M.getContext()) { Triple TT(Triple(M.getTargetTriple())); DXILVersion = TT.getDXILVersion(); ShaderStage = TT.getEnvironment(); @@ -369,7 +371,7 @@ Expected DXILOpBuilder::tryCreateOp(dxil::OpCode OpCode, OverloadTy = Args[ArgIndex]->getType(); } FunctionType *DXILOpFT = - getDXILOpFunctionType(Prop, M.getContext(), OverloadTy); + getDXILOpFunctionType(OpCode, M.getContext(), OverloadTy); std::optional OlIndexOrErr = getPropIndex(ArrayRef(Prop->Overloads), DXILVersion); @@ -379,11 +381,7 @@ Expected DXILOpBuilder::tryCreateOp(dxil::OpCode OpCode, uint16_t ValidTyMask = Prop->Overloads[*OlIndexOrErr].ValidTys; - // If we don't have an overload type, use the function's return type. This is - // a bit of a hack, but it's necessary to get the type suffix on unoverloaded - // DXIL ops correct, like `dx.op.threadId.i32`. - OverloadKind Kind = - getOverloadKind(OverloadTy ? OverloadTy : DXILOpFT->getReturnType()); + OverloadKind Kind = getOverloadKind(OverloadTy); // Check if the operation supports overload types and OverloadTy is valid // per the specified types for the operation @@ -418,13 +416,13 @@ Expected DXILOpBuilder::tryCreateOp(dxil::OpCode OpCode, // We need to inject the opcode as the first argument. SmallVector OpArgs; - OpArgs.push_back(B.getInt32(llvm::to_underlying(OpCode))); + OpArgs.push_back(IRB.getInt32(llvm::to_underlying(OpCode))); OpArgs.append(Args.begin(), Args.end()); - return B.CreateCall(DXILFn, OpArgs); + return IRB.CreateCall(DXILFn, OpArgs); } -CallInst *DXILOpBuilder::createOp(dxil::OpCode OpCode, ArrayRef &Args, +CallInst *DXILOpBuilder::createOp(dxil::OpCode OpCode, ArrayRef Args, Type *RetTy) { Expected Result = tryCreateOp(OpCode, Args, RetTy); if (Error E = Result.takeError()) diff --git a/llvm/lib/Target/DirectX/DXILOpBuilder.h b/llvm/lib/Target/DirectX/DXILOpBuilder.h index ff66f39a3ceb3..483d5ddc8b619 100644 --- a/llvm/lib/Target/DirectX/DXILOpBuilder.h +++ b/llvm/lib/Target/DirectX/DXILOpBuilder.h @@ -14,8 +14,9 @@ #include "DXILConstants.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/TargetParser/Triple.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/Support/Error.h" +#include "llvm/TargetParser/Triple.h" namespace llvm { class Module; @@ -29,29 +30,19 @@ namespace dxil { class DXILOpBuilder { public: - DXILOpBuilder(Module &M, IRBuilderBase &B); + DXILOpBuilder(Module &M); + + IRBuilder<> &getIRB() { return IRB; } /// Create a call instruction for the given DXIL op. The arguments /// must be valid for an overload of the operation. - CallInst *createOp(dxil::OpCode Op, ArrayRef &Args, + CallInst *createOp(dxil::OpCode Op, ArrayRef Args, Type *RetTy = nullptr); -#define DXIL_OPCODE(Op, Name) \ - CallInst *create##Name##Op(ArrayRef &Args, Type *RetTy = nullptr) { \ - return createOp(dxil::OpCode(Op), Args, RetTy); \ - } -#include "DXILOperation.inc" - /// Try to create a call instruction for the given DXIL op. Fails if the /// overload is invalid. Expected tryCreateOp(dxil::OpCode Op, ArrayRef Args, Type *RetTy = nullptr); -#define DXIL_OPCODE(Op, Name) \ - Expected tryCreate##Name##Op(ArrayRef &Args, \ - Type *RetTy = nullptr) { \ - return tryCreateOp(dxil::OpCode(Op), Args, RetTy); \ - } -#include "DXILOperation.inc" /// Return the name of the given opcode. static const char *getOpCodeName(dxil::OpCode DXILOp); @@ -63,7 +54,7 @@ class DXILOpBuilder { Type *OverloadType = nullptr); Module &M; - IRBuilderBase &B; + IRBuilder<> IRB; VersionTuple DXILVersion; Triple::EnvironmentType ShaderStage; }; diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index 5f84cdcfda6de..fb708a61dd318 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -1,15 +1,12 @@ -//===- DXILOpLower.cpp - Lowering LLVM intrinsic to DIXLOp function -------===// +//===- DXILOpLowering.cpp - Lowering to DXIL operations -------------------===// // // 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 passes and utilities to lower llvm intrinsic call -/// to DXILOp function call. -//===----------------------------------------------------------------------===// +#include "DXILOpLowering.h" #include "DXILConstants.h" #include "DXILIntrinsicExpansion.h" #include "DXILOpBuilder.h" @@ -73,77 +70,90 @@ static SmallVector argVectorFlatten(CallInst *Orig, return NewOperands; } -static void lowerIntrinsic(dxil::OpCode DXILOp, Function &F, Module &M) { - IRBuilder<> B(M.getContext()); - DXILOpBuilder OpBuilder(M, B); - for (User *U : make_early_inc_range(F.users())) { - CallInst *CI = dyn_cast(U); - if (!CI) - continue; - - SmallVector Args; - B.SetInsertPoint(CI); - if (isVectorArgExpansion(F)) { - SmallVector NewArgs = argVectorFlatten(CI, B); - Args.append(NewArgs.begin(), NewArgs.end()); - } else - Args.append(CI->arg_begin(), CI->arg_end()); - - Expected OpCallOrErr = OpBuilder.tryCreateOp(DXILOp, Args, - F.getReturnType()); - if (Error E = OpCallOrErr.takeError()) { - std::string Message(toString(std::move(E))); - DiagnosticInfoUnsupported Diag(*CI->getFunction(), Message, - CI->getDebugLoc()); - M.getContext().diagnose(Diag); - continue; +namespace { +class OpLowerer { + Module &M; + DXILOpBuilder OpBuilder; + +public: + OpLowerer(Module &M) : M(M), OpBuilder(M) {} + + void replaceFunction(Function &F, + llvm::function_ref ReplaceCall) { + for (User *U : make_early_inc_range(F.users())) { + CallInst *CI = dyn_cast(U); + if (!CI) + continue; + + if (Error E = ReplaceCall(CI)) { + std::string Message(toString(std::move(E))); + DiagnosticInfoUnsupported Diag(*CI->getFunction(), Message, + CI->getDebugLoc()); + M.getContext().diagnose(Diag); + continue; + } } - CallInst *OpCall = *OpCallOrErr; + if (F.user_empty()) + F.eraseFromParent(); + } - CI->replaceAllUsesWith(OpCall); - CI->eraseFromParent(); + void replaceFunctionWithOp(Function &F, dxil::OpCode DXILOp) { + bool IsVectorArgExpansion = isVectorArgExpansion(F); + replaceFunction(F, [&](CallInst *CI) -> Error { + SmallVector Args; + OpBuilder.getIRB().SetInsertPoint(CI); + if (IsVectorArgExpansion) { + SmallVector NewArgs = argVectorFlatten(CI, OpBuilder.getIRB()); + Args.append(NewArgs.begin(), NewArgs.end()); + } else + Args.append(CI->arg_begin(), CI->arg_end()); + + Expected OpCall = + OpBuilder.tryCreateOp(DXILOp, Args, F.getReturnType()); + if (Error E = OpCall.takeError()) + return E; + + CI->replaceAllUsesWith(*OpCall); + CI->eraseFromParent(); + return Error::success(); + }); } - if (F.user_empty()) - F.eraseFromParent(); -} -static bool lowerIntrinsics(Module &M) { - bool Updated = false; + bool lowerIntrinsics() { + bool Updated = false; - for (Function &F : make_early_inc_range(M.functions())) { - if (!F.isDeclaration()) - continue; - Intrinsic::ID ID = F.getIntrinsicID(); - switch (ID) { - default: - continue; + for (Function &F : make_early_inc_range(M.functions())) { + if (!F.isDeclaration()) + continue; + Intrinsic::ID ID = F.getIntrinsicID(); + switch (ID) { + default: + continue; #define DXIL_OP_INTRINSIC(OpCode, Intrin) \ case Intrin: \ - lowerIntrinsic(OpCode, F, M); \ + replaceFunctionWithOp(F, OpCode); \ break; #include "DXILOperation.inc" + } + Updated = true; } - Updated = true; - } - return Updated; -} - -namespace { -/// A pass that transforms external global definitions into declarations. -class DXILOpLowering : public PassInfoMixin { -public: - PreservedAnalyses run(Module &M, ModuleAnalysisManager &) { - if (lowerIntrinsics(M)) - return PreservedAnalyses::none(); - return PreservedAnalyses::all(); + return Updated; } }; } // namespace +PreservedAnalyses DXILOpLowering::run(Module &M, ModuleAnalysisManager &) { + if (OpLowerer(M).lowerIntrinsics()) + return PreservedAnalyses::none(); + return PreservedAnalyses::all(); +} + namespace { class DXILOpLoweringLegacy : public ModulePass { public: - bool runOnModule(Module &M) override { return lowerIntrinsics(M); } + bool runOnModule(Module &M) override { + return OpLowerer(M).lowerIntrinsics(); + } StringRef getPassName() const override { return "DXIL Op Lowering"; } DXILOpLoweringLegacy() : ModulePass(ID) {} diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.h b/llvm/lib/Target/DirectX/DXILOpLowering.h new file mode 100644 index 0000000000000..fe357da7bb905 --- /dev/null +++ b/llvm/lib/Target/DirectX/DXILOpLowering.h @@ -0,0 +1,27 @@ +//===- DXILOpLowering.h - Lowering to DXIL operations -----------*- C++ -*-===// +// +// 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 Pass for lowering llvm intrinsics into DXIL operations. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_DIRECTX_DXILOPLOWERING_H +#define LLVM_LIB_TARGET_DIRECTX_DXILOPLOWERING_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class DXILOpLowering : public PassInfoMixin { +public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_DIRECTX_DXILOPLOWERING_H diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp index 99cc4067b1d62..7d2abb7078b8a 100644 --- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp +++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp @@ -1,16 +1,12 @@ -//===- DXILPrettyPrinter.cpp - DXIL Resource helper objects ---------------===// +//===- DXILPrettyPrinter.cpp - Print resources for textual DXIL -----------===// // // 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 a pass for pretty printing DXIL metadata into IR -/// comments when printing assembly output. -/// -//===----------------------------------------------------------------------===// +#include "DXILPrettyPrinter.h" #include "DXILResourceAnalysis.h" #include "DirectX.h" #include "llvm/ADT/StringRef.h" @@ -20,18 +16,30 @@ using namespace llvm; +static void prettyPrintResources(raw_ostream &OS, + const dxil::Resources &MDResources) { + MDResources.print(OS); +} + +PreservedAnalyses DXILPrettyPrinterPass::run(Module &M, + ModuleAnalysisManager &MAM) { + const dxil::Resources &MDResources = MAM.getResult(M); + prettyPrintResources(OS, MDResources); + return PreservedAnalyses::all(); +} + namespace { -class DXILPrettyPrinter : public llvm::ModulePass { +class DXILPrettyPrinterLegacy : public llvm::ModulePass { raw_ostream &OS; // raw_ostream to print to. public: static char ID; - DXILPrettyPrinter() : ModulePass(ID), OS(dbgs()) { - initializeDXILPrettyPrinterPass(*PassRegistry::getPassRegistry()); + DXILPrettyPrinterLegacy() : ModulePass(ID), OS(dbgs()) { + initializeDXILPrettyPrinterLegacyPass(*PassRegistry::getPassRegistry()); } - explicit DXILPrettyPrinter(raw_ostream &O) : ModulePass(ID), OS(O) { - initializeDXILPrettyPrinterPass(*PassRegistry::getPassRegistry()); + explicit DXILPrettyPrinterLegacy(raw_ostream &O) : ModulePass(ID), OS(O) { + initializeDXILPrettyPrinterLegacyPass(*PassRegistry::getPassRegistry()); } StringRef getPassName() const override { @@ -46,19 +54,19 @@ class DXILPrettyPrinter : public llvm::ModulePass { }; } // namespace -char DXILPrettyPrinter::ID = 0; -INITIALIZE_PASS_BEGIN(DXILPrettyPrinter, "dxil-pretty-printer", +char DXILPrettyPrinterLegacy::ID = 0; +INITIALIZE_PASS_BEGIN(DXILPrettyPrinterLegacy, "dxil-pretty-printer", "DXIL Metadata Pretty Printer", true, true) INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper) -INITIALIZE_PASS_END(DXILPrettyPrinter, "dxil-pretty-printer", +INITIALIZE_PASS_END(DXILPrettyPrinterLegacy, "dxil-pretty-printer", "DXIL Metadata Pretty Printer", true, true) -bool DXILPrettyPrinter::runOnModule(Module &M) { +bool DXILPrettyPrinterLegacy::runOnModule(Module &M) { dxil::Resources &Res = getAnalysis().getDXILResource(); Res.print(OS); return false; } -ModulePass *llvm::createDXILPrettyPrinterPass(raw_ostream &OS) { - return new DXILPrettyPrinter(OS); +ModulePass *llvm::createDXILPrettyPrinterLegacyPass(raw_ostream &OS) { + return new DXILPrettyPrinterLegacy(OS); } diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.h b/llvm/lib/Target/DirectX/DXILPrettyPrinter.h new file mode 100644 index 0000000000000..84e17ac0f2ec6 --- /dev/null +++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.h @@ -0,0 +1,33 @@ +//===- DXILPrettyPrinter.h - Print resources for textual DXIL ---*- C++ -*-===// +// +// 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 a pass for pretty printing DXIL metadata into IR +// comments when printing assembly output. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_DIRECTX_DXILPRETTYPRINTER_H +#define LLVM_TARGET_DIRECTX_DXILPRETTYPRINTER_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +/// A pass that prints resources in a format suitable for textual DXIL. +class DXILPrettyPrinterPass : public PassInfoMixin { + raw_ostream &OS; + +public: + explicit DXILPrettyPrinterPass(raw_ostream &OS) : OS(OS) {} + + PreservedAnalyses run(Module &M, ModuleAnalysisManager &); +}; + +} // namespace llvm + +#endif // LLVM_TARGET_DIRECTX_DXILPRETTYPRINTER_H diff --git a/llvm/lib/Target/DirectX/DXILResourceAnalysis.h b/llvm/lib/Target/DirectX/DXILResourceAnalysis.h index 3a2b8a9fd39d5..26d9237d51b49 100644 --- a/llvm/lib/Target/DirectX/DXILResourceAnalysis.h +++ b/llvm/lib/Target/DirectX/DXILResourceAnalysis.h @@ -57,6 +57,10 @@ class DXILResourceMDWrapper : public ModulePass { /// Calculate the DXILResource for the module. bool runOnModule(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + void print(raw_ostream &O, const Module *M = nullptr) const override; }; } // namespace llvm diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp index 583bce0f50e70..55b3d94568426 100644 --- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp +++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp @@ -1,13 +1,12 @@ -//===- DXILTranslateMetadata.cpp - Pass to emit DXIL metadata ---*- C++ -*-===// +//===- DXILTranslateMetadata.cpp - Pass to emit DXIL metadata -------------===// // // 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 "DXILTranslateMetadata.h" #include "DXILMetadata.h" #include "DXILResource.h" #include "DXILResourceAnalysis.h" @@ -23,13 +22,37 @@ using namespace llvm; using namespace llvm::dxil; +static void translateMetadata(Module &M, const dxil::Resources &MDResources, + const ComputedShaderFlags &ShaderFlags) { + dxil::ValidatorVersionMD ValVerMD(M); + if (ValVerMD.isEmpty()) + ValVerMD.update(VersionTuple(1, 0)); + dxil::createShaderModelMD(M); + dxil::createDXILVersionMD(M); + + MDResources.write(M); + + dxil::createEntryMD(M, static_cast(ShaderFlags)); +} + +PreservedAnalyses DXILTranslateMetadata::run(Module &M, + ModuleAnalysisManager &MAM) { + const dxil::Resources &MDResources = MAM.getResult(M); + const ComputedShaderFlags &ShaderFlags = + MAM.getResult(M); + + translateMetadata(M, MDResources, ShaderFlags); + + return PreservedAnalyses::all(); +} + namespace { -class DXILTranslateMetadata : public ModulePass { +class DXILTranslateMetadataLegacy : public ModulePass { public: static char ID; // Pass identification, replacement for typeid - explicit DXILTranslateMetadata() : ModulePass(ID) {} + explicit DXILTranslateMetadataLegacy() : ModulePass(ID) {} - StringRef getPassName() const override { return "DXIL Metadata Emit"; } + StringRef getPassName() const override { return "DXIL Translate Metadata"; } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); @@ -37,39 +60,28 @@ class DXILTranslateMetadata : public ModulePass { AU.addRequired(); } - bool runOnModule(Module &M) override; + bool runOnModule(Module &M) override { + const dxil::Resources &MDResources = + getAnalysis().getDXILResource(); + const ComputedShaderFlags &ShaderFlags = + getAnalysis().getShaderFlags(); + + translateMetadata(M, MDResources, ShaderFlags); + return true; + } }; } // namespace -bool DXILTranslateMetadata::runOnModule(Module &M) { - - dxil::ValidatorVersionMD ValVerMD(M); - if (ValVerMD.isEmpty()) - ValVerMD.update(VersionTuple(1, 0)); - dxil::createShaderModelMD(M); - dxil::createDXILVersionMD(M); - - const dxil::Resources &Res = - getAnalysis().getDXILResource(); - Res.write(M); - - const uint64_t Flags = static_cast( - getAnalysis().getShaderFlags()); - dxil::createEntryMD(M, Flags); - - return false; -} - -char DXILTranslateMetadata::ID = 0; +char DXILTranslateMetadataLegacy::ID = 0; -ModulePass *llvm::createDXILTranslateMetadataPass() { - return new DXILTranslateMetadata(); +ModulePass *llvm::createDXILTranslateMetadataLegacyPass() { + return new DXILTranslateMetadataLegacy(); } -INITIALIZE_PASS_BEGIN(DXILTranslateMetadata, "dxil-metadata-emit", - "DXIL Metadata Emit", false, false) +INITIALIZE_PASS_BEGIN(DXILTranslateMetadataLegacy, "dxil-translate-metadata", + "DXIL Translate Metadata", false, false) INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper) INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper) -INITIALIZE_PASS_END(DXILTranslateMetadata, "dxil-metadata-emit", - "DXIL Metadata Emit", false, false) +INITIALIZE_PASS_END(DXILTranslateMetadataLegacy, "dxil-translate-metadata", + "DXIL Translate Metadata", false, false) diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.h b/llvm/lib/Target/DirectX/DXILTranslateMetadata.h new file mode 100644 index 0000000000000..f3f5eb1901406 --- /dev/null +++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.h @@ -0,0 +1,24 @@ +//===- DXILTranslateMetadata.h - Pass to emit DXIL metadata -----*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_DIRECTX_DXILTRANSLATEMETADATA_H +#define LLVM_TARGET_DIRECTX_DXILTRANSLATEMETADATA_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +/// A pass that transforms DXIL Intrinsics that don't have DXIL opCodes +class DXILTranslateMetadata : public PassInfoMixin { +public: + PreservedAnalyses run(Module &M, ModuleAnalysisManager &); +}; + +} // namespace llvm + +#endif // LLVM_TARGET_DIRECTX_DXILTRANSLATEMETADATA_H diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h index d056ae2bc488e..963c39ace3af9 100644 --- a/llvm/lib/Target/DirectX/DirectX.h +++ b/llvm/lib/Target/DirectX/DirectX.h @@ -41,19 +41,19 @@ void initializeDXILOpLoweringLegacyPass(PassRegistry &); ModulePass *createDXILOpLoweringLegacyPass(); /// Initializer for DXILTranslateMetadata. -void initializeDXILTranslateMetadataPass(PassRegistry &); +void initializeDXILTranslateMetadataLegacyPass(PassRegistry &); /// Pass to emit metadata for DXIL. -ModulePass *createDXILTranslateMetadataPass(); +ModulePass *createDXILTranslateMetadataLegacyPass(); /// Initializer for DXILTranslateMetadata. void initializeDXILResourceMDWrapperPass(PassRegistry &); /// Pass to pretty print DXIL metadata. -ModulePass *createDXILPrettyPrinterPass(raw_ostream &OS); +ModulePass *createDXILPrettyPrinterLegacyPass(raw_ostream &OS); /// Initializer for DXILPrettyPrinter. -void initializeDXILPrettyPrinterPass(PassRegistry &); +void initializeDXILPrettyPrinterLegacyPass(PassRegistry &); /// Initializer for dxil::ShaderFlagsAnalysisWrapper pass. void initializeShaderFlagsAnalysisWrapperPass(PassRegistry &); diff --git a/llvm/lib/Target/DirectX/DirectXPassRegistry.def b/llvm/lib/Target/DirectX/DirectXPassRegistry.def index 7544172ab94e4..a3e051b173d89 100644 --- a/llvm/lib/Target/DirectX/DirectXPassRegistry.def +++ b/llvm/lib/Target/DirectX/DirectXPassRegistry.def @@ -23,7 +23,10 @@ MODULE_ANALYSIS("dxil-resource-md", DXILResourceMDAnalysis()) #ifndef MODULE_PASS #define MODULE_PASS(NAME, CREATE_PASS) #endif +MODULE_PASS("dxil-intrinsic-expansion", DXILIntrinsicExpansion()) +MODULE_PASS("dxil-op-lower", DXILOpLowering()) +MODULE_PASS("dxil-pretty-printer", DXILPrettyPrinterPass(dbgs())) +MODULE_PASS("dxil-translate-metadata", DXILTranslateMetadata()) // TODO: rename to print after NPM switch MODULE_PASS("print-dx-shader-flags", dxil::ShaderFlagsAnalysisPrinter(dbgs())) -MODULE_PASS("print-dxil-resource-md", DXILResourceMDPrinterPass(dbgs())) #undef MODULE_PASS diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp index 92bd69b69684f..a578ad1452560 100644 --- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp +++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp @@ -12,8 +12,12 @@ //===----------------------------------------------------------------------===// #include "DirectXTargetMachine.h" +#include "DXILIntrinsicExpansion.h" +#include "DXILOpLowering.h" +#include "DXILPrettyPrinter.h" #include "DXILResourceAnalysis.h" #include "DXILShaderFlags.h" +#include "DXILTranslateMetadata.h" #include "DXILWriter/DXILWriterPass.h" #include "DirectX.h" #include "DirectXSubtarget.h" @@ -45,7 +49,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { initializeWriteDXILPassPass(*PR); initializeDXContainerGlobalsPass(*PR); initializeDXILOpLoweringLegacyPass(*PR); - initializeDXILTranslateMetadataPass(*PR); + initializeDXILTranslateMetadataLegacyPass(*PR); initializeDXILResourceMDWrapperPass(*PR); initializeShaderFlagsAnalysisWrapperPass(*PR); } @@ -79,7 +83,7 @@ class DirectXPassConfig : public TargetPassConfig { void addCodeGenPrepare() override { addPass(createDXILIntrinsicExpansionLegacyPass()); addPass(createDXILOpLoweringLegacyPass()); - addPass(createDXILTranslateMetadataPass()); + addPass(createDXILTranslateMetadataLegacyPass()); addPass(createDXILPrepareModulePass()); } }; @@ -116,7 +120,7 @@ bool DirectXTargetMachine::addPassesToEmitFile( switch (FileType) { case CodeGenFileType::AssemblyFile: - PM.add(createDXILPrettyPrinterPass(Out)); + PM.add(createDXILPrettyPrinterLegacyPass(Out)); PM.add(createPrintModulePass(Out, "", true)); break; case CodeGenFileType::ObjectFile: diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll index 4349adb8ef8eb..65802c6d1ff87 100644 --- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll +++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll @@ -46,14 +46,14 @@ define void @test_typedbuffer() { ; Buffer Buf[24] : register(t3, space5) %typed2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0) @llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_0_0t( - i32 2, i32 7, i32 24, i32 0, i1 false) + i32 5, i32 3, i32 24, i32 0, i1 false) ; CHECK: Binding for %typed2 ; CHECK: Symbol: ptr undef ; CHECK: Name: "" ; CHECK: Binding: ; CHECK: Record ID: 0 - ; CHECK: Space: 2 - ; CHECK: Lower Bound: 7 + ; CHECK: Space: 5 + ; CHECK: Lower Bound: 3 ; CHECK: Size: 24 ; CHECK: Class: SRV ; CHECK: Kind: TypedBuffer diff --git a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll index b9a8e3e80567e..fb31833dd5139 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -passes=dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel6.0-vertex" diff --git a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll index fdd21d627829b..5944acc3b5b4b 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -passes=dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel6.8-compute" diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-as.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-as.ll index d2625fc8b96a9..96d04f948c9b8 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-as.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-as.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel6-amplification" diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-cs.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-cs.ll index 24eb0d608d8bb..8cba445bcb01e 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-cs.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-cs.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -dxil-prepare %s | FileCheck %s --check-prefix=REMOVE_EXTRA_ATTRIBUTE ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-gs.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-gs.ll index 5c28c9305f01b..662620cf9f95c 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-gs.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-gs.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel6.6-geometry" diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-hs.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-hs.ll index e60023d1b3a5f..b405f8e915a32 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-hs.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-hs.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel6.6-hull" diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-lib.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-lib.ll index 7f0bea95c0482..26f3d287242ed 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-lib.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-lib.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel6.3-library" diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ms.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ms.ll index dd033b9a9722b..422d4add912f3 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ms.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ms.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel6.6-mesh" diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ps.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ps.ll index 47da321df3e42..cdb9a6f0f6a4f 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ps.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ps.ll @@ -1,5 +1,4 @@ - -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel5.0-pixel" diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-vs.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-vs.ll index dcc68586dd4b9..6b3501cc1dbaf 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-vs.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-vs.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata %s | FileCheck %s ; RUN: opt -S -passes="print" -disable-output %s 2>&1 | FileCheck %s --check-prefix=ANALYSIS target triple = "dxil-pc-shadermodel-vertex" diff --git a/llvm/test/CodeGen/DirectX/UAVMetadata.ll b/llvm/test/CodeGen/DirectX/UAVMetadata.ll index bdad9fd40c9bd..2c242ec08eda5 100644 --- a/llvm/test/CodeGen/DirectX/UAVMetadata.ll +++ b/llvm/test/CodeGen/DirectX/UAVMetadata.ll @@ -1,5 +1,5 @@ -; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s -; RUN: opt -S --passes="print-dxil-resource-md" < %s 2>&1 | FileCheck %s --check-prefix=PRINT +; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s +; RUN: opt -S --passes="dxil-pretty-printer" < %s 2>&1 | FileCheck %s --check-prefix=PRINT ; RUN: llc %s --filetype=asm -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" diff --git a/llvm/test/CodeGen/DirectX/any.ll b/llvm/test/CodeGen/DirectX/any.ll index ceb8077af311d..e32aa389a81a5 100644 --- a/llvm/test/CodeGen/DirectX/any.ll +++ b/llvm/test/CodeGen/DirectX/any.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.0-library < %s | FileCheck %s +; RUN: opt -S -passes=dxil-intrinsic-expansion,dxil-op-lower -mtriple=dxil-pc-shadermodel6.0-library < %s | FileCheck %s ; Make sure dxil operation function calls for any are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/cbuf.ll b/llvm/test/CodeGen/DirectX/cbuf.ll index 38f08fad995d1..7589da5e15bd7 100644 --- a/llvm/test/CodeGen/DirectX/cbuf.ll +++ b/llvm/test/CodeGen/DirectX/cbuf.ll @@ -1,5 +1,5 @@ -; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s --check-prefix=DXILMD -; RUN: opt -S --passes="print-dxil-resource-md" < %s 2>&1 | FileCheck %s --check-prefix=PRINT +; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s --check-prefix=DXILMD +; RUN: opt -S --passes="dxil-pretty-printer" < %s 2>&1 | FileCheck %s --check-prefix=PRINT target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" target triple = "dxil-unknown-shadermodel6.7-library" diff --git a/llvm/test/CodeGen/DirectX/dxil_ver.ll b/llvm/test/CodeGen/DirectX/dxil_ver.ll index e9923a3abce02..3c1d2e8102009 100644 --- a/llvm/test/CodeGen/DirectX/dxil_ver.ll +++ b/llvm/test/CodeGen/DirectX/dxil_ver.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" target triple = "dxil-pc-shadermodel6.3-library" diff --git a/llvm/test/CodeGen/DirectX/floor.ll b/llvm/test/CodeGen/DirectX/floor.ll index f667cab4aa249..f79f160e51e3b 100644 --- a/llvm/test/CodeGen/DirectX/floor.ll +++ b/llvm/test/CodeGen/DirectX/floor.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s +; RUN: opt -S -passes=dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s ; Make sure dxil operation function calls for floor are generated for float and half. diff --git a/llvm/test/CodeGen/DirectX/legacy_cb_layout_0.ll b/llvm/test/CodeGen/DirectX/legacy_cb_layout_0.ll index 0cfb839746b93..1a618092c5fed 100644 --- a/llvm/test/CodeGen/DirectX/legacy_cb_layout_0.ll +++ b/llvm/test/CodeGen/DirectX/legacy_cb_layout_0.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s --check-prefix=DXILMD +; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s --check-prefix=DXILMD target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" target triple = "dxil-unknown-shadermodel6.7-library" diff --git a/llvm/test/CodeGen/DirectX/legacy_cb_layout_1.ll b/llvm/test/CodeGen/DirectX/legacy_cb_layout_1.ll index b6d29f8d18d79..6886f2690209d 100644 --- a/llvm/test/CodeGen/DirectX/legacy_cb_layout_1.ll +++ b/llvm/test/CodeGen/DirectX/legacy_cb_layout_1.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s --check-prefix=DXILMD +; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s --check-prefix=DXILMD target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" target triple = "dxil-unknown-shadermodel6.7-library" diff --git a/llvm/test/CodeGen/DirectX/legacy_cb_layout_2.ll b/llvm/test/CodeGen/DirectX/legacy_cb_layout_2.ll index d023d7906fdc5..3b08b25542201 100644 --- a/llvm/test/CodeGen/DirectX/legacy_cb_layout_2.ll +++ b/llvm/test/CodeGen/DirectX/legacy_cb_layout_2.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s --check-prefix=DXILMD +; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s --check-prefix=DXILMD target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" target triple = "dxil-unknown-shadermodel6.7-library" diff --git a/llvm/test/CodeGen/DirectX/legacy_cb_layout_3.ll b/llvm/test/CodeGen/DirectX/legacy_cb_layout_3.ll index 38c2cd18b5ca1..f01afbdab9673 100644 --- a/llvm/test/CodeGen/DirectX/legacy_cb_layout_3.ll +++ b/llvm/test/CodeGen/DirectX/legacy_cb_layout_3.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s --check-prefix=DXILMD +; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s --check-prefix=DXILMD target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" target triple = "dxil-unknown-shadermodel6.7-library" diff --git a/llvm/test/CodeGen/DirectX/lib_entry.ll b/llvm/test/CodeGen/DirectX/lib_entry.ll index 5254a08805588..9aa63c26ce845 100644 --- a/llvm/test/CodeGen/DirectX/lib_entry.ll +++ b/llvm/test/CodeGen/DirectX/lib_entry.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -dxil-metadata-emit < %s | FileCheck %s +; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" target triple = "dxil-unknown-shadermodel6.7-library" diff --git a/llvm/test/Frontend/HLSL/empty_cs_entry.ll b/llvm/test/Frontend/HLSL/empty_cs_entry.ll index 45b0faeaa44d4..32736aeeb542c 100644 --- a/llvm/test/Frontend/HLSL/empty_cs_entry.ll +++ b/llvm/test/Frontend/HLSL/empty_cs_entry.ll @@ -1,4 +1,4 @@ -; RUN: %if directx-registered-target %{ opt -S -dxil-metadata-emit < %s | FileCheck %s --check-prefix=DXIL-CHECK %} +; RUN: %if directx-registered-target %{ opt -S -dxil-translate-metadata < %s | FileCheck %s --check-prefix=DXIL-CHECK %} ; RUN: %if spirv-registered-target %{ llc %s -mtriple=spirv-unknown-unknown -o - | FileCheck %s --check-prefix=SPIRV-CHECK %} target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" diff --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp index 53791618e80fe..9cc1b5ccb8acb 100644 --- a/llvm/utils/TableGen/DXILEmitter.cpp +++ b/llvm/utils/TableGen/DXILEmitter.cpp @@ -18,7 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" -#include "llvm/CodeGenTypes/MachineValueType.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/DXILABI.h" #include "llvm/Support/VersionTuple.h" #include "llvm/TableGen/Error.h" @@ -54,40 +54,6 @@ struct DXILOperationDesc { }; } // end anonymous namespace -/// Return dxil::ParameterKind corresponding to input LLVMType record -/// -/// \param R TableGen def record of class LLVMType -/// \return ParameterKind As defined in llvm/Support/DXILABI.h - -static ParameterKind getParameterKind(const Record *R) { - auto VTRec = R->getValueAsDef("VT"); - switch (getValueType(VTRec)) { - case MVT::isVoid: - return ParameterKind::Void; - case MVT::f16: - return ParameterKind::Half; - case MVT::f32: - return ParameterKind::Float; - case MVT::f64: - return ParameterKind::Double; - case MVT::i1: - return ParameterKind::I1; - case MVT::i8: - return ParameterKind::I8; - case MVT::i16: - return ParameterKind::I16; - case MVT::i32: - return ParameterKind::I32; - case MVT::fAny: - case MVT::iAny: - case MVT::Any: - return ParameterKind::Overload; - default: - llvm_unreachable( - "Support for specified parameter type not yet implemented"); - } -} - /// In-place sort TableGen records of class with a field /// Version dxil_version /// in the ascending version order. @@ -134,10 +100,9 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { // llvm/IR/Intrinsics.td OverloadParamIndex = -1; // A sigil meaning none. for (unsigned i = 0; i < ParamTypeRecsSize; i++) { - auto TR = ParamTypeRecs[i]; + Record *TR = ParamTypeRecs[i]; // Track operation parameter indices of any overload types - auto isAny = TR->getValueAsInt("isAny"); - if (isAny == 1) { + if (TR->getValueAsInt("isOverload")) { if (OverloadParamIndex != -1) { assert(TR == ParamTypeRecs[OverloadParamIndex] && "Specification of multiple differing overload parameter types " @@ -148,8 +113,6 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { if (OverloadParamIndex <= 0) OverloadParamIndex = i; } - if (TR->isAnonymous()) - PrintFatalError(TR, "Only concrete types are allowed here"); OpTypes.emplace_back(TR); } @@ -208,71 +171,23 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) { } } -/// Return a string representation of ParameterKind enum -/// \param Kind Parameter Kind enum value -/// \return std::string string representation of input Kind -static std::string getParameterKindStr(ParameterKind Kind) { - switch (Kind) { - case ParameterKind::Invalid: - return "Invalid"; - case ParameterKind::Void: - return "Void"; - case ParameterKind::Half: - return "Half"; - case ParameterKind::Float: - return "Float"; - case ParameterKind::Double: - return "Double"; - case ParameterKind::I1: - return "I1"; - case ParameterKind::I8: - return "I8"; - case ParameterKind::I16: - return "I16"; - case ParameterKind::I32: - return "I32"; - case ParameterKind::I64: - return "I64"; - case ParameterKind::Overload: - return "Overload"; - case ParameterKind::CBufferRet: - return "CBufferRet"; - case ParameterKind::ResourceRet: - return "ResourceRet"; - case ParameterKind::DXILHandle: - return "DXILHandle"; - } - llvm_unreachable("Unknown llvm::dxil::ParameterKind enum"); -} - /// Return a string representation of OverloadKind enum that maps to /// input LLVMType record /// \param R TableGen def record of class LLVMType /// \return std::string string representation of OverloadKind -static std::string getOverloadKindStr(const Record *R) { - Record *VTRec = R->getValueAsDef("VT"); - switch (getValueType(VTRec)) { - case MVT::f16: - return "OverloadKind::HALF"; - case MVT::f32: - return "OverloadKind::FLOAT"; - case MVT::f64: - return "OverloadKind::DOUBLE"; - case MVT::i1: - return "OverloadKind::I1"; - case MVT::i8: - return "OverloadKind::I8"; - case MVT::i16: - return "OverloadKind::I16"; - case MVT::i32: - return "OverloadKind::I32"; - case MVT::i64: - return "OverloadKind::I64"; - default: - llvm_unreachable("Support for specified fixed type option for overload " - "type not supported"); - } +static StringRef getOverloadKindStr(const Record *R) { + // TODO: This is a hack. We need to rework how we're handling the set of + // overloads to avoid this business with the separate OverloadKind enum. + return StringSwitch(R->getName()) + .Case("HalfTy", "OverloadKind::HALF") + .Case("FloatTy", "OverloadKind::FLOAT") + .Case("DoubleTy", "OverloadKind::DOUBLE") + .Case("Int1Ty", "OverloadKind::I1") + .Case("Int8Ty", "OverloadKind::I8") + .Case("Int16Ty", "OverloadKind::I16") + .Case("Int32Ty", "OverloadKind::I32") + .Case("Int64Ty", "OverloadKind::I64"); } /// Return a string representation of valid overload information denoted @@ -417,8 +332,7 @@ static void emitDXILOpCodes(std::vector &Ops, } /// Emit a list of DXIL op classes -static void emitDXILOpClasses(RecordKeeper &Records, - raw_ostream &OS) { +static void emitDXILOpClasses(RecordKeeper &Records, raw_ostream &OS) { OS << "#ifdef DXIL_OPCLASS\n"; std::vector OpClasses = Records.getAllDerivedDefinitions("DXILOpClass"); @@ -428,6 +342,35 @@ static void emitDXILOpClasses(RecordKeeper &Records, OS << "#endif\n\n"; } +/// Emit a list of DXIL op parameter types +static void emitDXILOpParamTypes(RecordKeeper &Records, raw_ostream &OS) { + OS << "#ifdef DXIL_OP_PARAM_TYPE\n"; + std::vector OpClasses = + Records.getAllDerivedDefinitions("DXILOpParamType"); + for (Record *OpClass : OpClasses) + OS << "DXIL_OP_PARAM_TYPE(" << OpClass->getName() << ")\n"; + OS << "#undef DXIL_OP_PARAM_TYPE\n"; + OS << "#endif\n\n"; +} + +/// Emit a list of DXIL op function types +static void emitDXILOpFunctionTypes(ArrayRef Ops, + raw_ostream &OS) { + OS << "#ifndef DXIL_OP_FUNCTION_TYPE\n"; + OS << "#define DXIL_OP_FUNCTION_TYPE(OpCode, RetType, ...)\n"; + OS << "#endif\n"; + for (const DXILOperationDesc &Op : Ops) { + OS << "DXIL_OP_FUNCTION_TYPE(dxil::OpCode::" << Op.OpName; + for (const Record *Rec : Op.OpTypes) + OS << ", dxil::OpParamType::" << Rec->getName(); + // If there are no arguments, we need an empty comma for the varargs + if (Op.OpTypes.size() == 1) + OS << ", "; + OS << ")\n"; + } + OS << "#undef DXIL_OP_FUNCTION_TYPE\n"; +} + /// Emit map of DXIL operation to LLVM or DirectX intrinsic /// \param A vector of DXIL Ops /// \param Output stream @@ -454,9 +397,7 @@ static void emitDXILOperationTable(std::vector &Ops, // Collect Names. SequenceToOffsetTable OpClassStrings; SequenceToOffsetTable OpStrings; - SequenceToOffsetTable> Parameters; - StringMap> ParameterMap; StringSet<> ClassSet; for (auto &Op : Ops) { OpStrings.add(Op.OpName); @@ -465,18 +406,11 @@ static void emitDXILOperationTable(std::vector &Ops, continue; ClassSet.insert(Op.OpClass); OpClassStrings.add(Op.OpClass.data()); - SmallVector ParamKindVec; - for (unsigned i = 0; i < Op.OpTypes.size(); i++) { - ParamKindVec.emplace_back(getParameterKind(Op.OpTypes[i])); - } - ParameterMap[Op.OpClass] = ParamKindVec; - Parameters.add(ParamKindVec); } // Layout names. OpStrings.layout(); OpClassStrings.layout(); - Parameters.layout(); // Emit access function getOpcodeProperty() that embeds DXIL Operation table // with entries of type struct OpcodeProperty. @@ -492,8 +426,7 @@ static void emitDXILOperationTable(std::vector &Ops, << getOverloadMaskString(Op.OverloadRecs) << ", " << getStageMaskString(Op.StageRecs) << ", " << getAttributeMaskString(Op.AttrRecs) << ", " << Op.OverloadParamIndex - << ", " << Op.OpTypes.size() << ", " - << Parameters.get(ParameterMap[Op.OpClass]) << " }"; + << " }"; Prefix = ",\n"; } OS << " };\n"; @@ -531,21 +464,6 @@ static void emitDXILOperationTable(std::vector &Ops, OS << " unsigned Index = Prop.OpCodeClassNameOffset;\n"; OS << " return DXILOpCodeClassNameTable + Index;\n"; - OS << "}\n "; - - OS << "static const ParameterKind *getOpCodeParameterKind(const " - "OpCodeProperty &Prop) " - "{\n\n"; - OS << " static const ParameterKind DXILOpParameterKindTable[] = {\n"; - Parameters.emit( - OS, - [](raw_ostream &ParamOS, ParameterKind Kind) { - ParamOS << "ParameterKind::" << getParameterKindStr(Kind); - }, - "ParameterKind::Invalid"); - OS << " };\n\n"; - OS << " unsigned Index = Prop.ParameterTableOffset;\n"; - OS << " return DXILOpParameterKindTable + Index;\n"; OS << "}\n\n"; } @@ -611,6 +529,8 @@ static void EmitDXILOperation(RecordKeeper &Records, raw_ostream &OS) { emitDXILOpCodes(DXILOps, OS); emitDXILOpClasses(Records, OS); + emitDXILOpParamTypes(Records, OS); + emitDXILOpFunctionTypes(DXILOps, OS); emitDXILIntrinsicMap(DXILOps, OS); OS << "#ifdef DXIL_OP_OPERATION_TABLE\n\n"; emitDXILOperationTableDataStructs(Records, OS); From 6fd9721d89e117dda21501ff5c64e65559f10f67 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Fri, 23 Aug 2024 12:52:58 -0700 Subject: [PATCH 2/2] fix comment Created using spr 1.3.5-bogner --- llvm/test/CodeGen/DirectX/CreateHandle.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/DirectX/CreateHandle.ll b/llvm/test/CodeGen/DirectX/CreateHandle.ll index f0389b028e574..13d59c6caf6c9 100644 --- a/llvm/test/CodeGen/DirectX/CreateHandle.ll +++ b/llvm/test/CodeGen/DirectX/CreateHandle.ll @@ -19,7 +19,7 @@ define void @test_buffers() { ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 6, i1 false) ; Buffer Buf[24] : register(t3, space5) - ; Buffer typed2 = Buf[5] + ; Buffer typed2 = Buf[4] ; Note that the index below is 3 + 4 = 7 %typed2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0) @llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_0_0_0t(