diff --git a/llvm/docs/DirectX/DXILOpTableGenDesign.rst b/llvm/docs/DirectX/DXILOpTableGenDesign.rst index 5f3ac75e82494..50d801bd05efd 100644 --- a/llvm/docs/DirectX/DXILOpTableGenDesign.rst +++ b/llvm/docs/DirectX/DXILOpTableGenDesign.rst @@ -24,12 +24,12 @@ DXIL Operations are represented in one of the following `two ways These are collectively referred to as `LLVM Intrinsics` in this note. -Following is the complete list of attributes of DXIL Ops with the corresponding field name -as used in ``hctdb.py``. A DXIL Op is represented by a set of associated attributes. These -are consumed in DXIL backend passes as well as in other usage scenarios such as validation, +Following is the complete list of properties of DXIL Ops with the corresponding field name +as used in ``hctdb.py``. A DXIL Op is represented by a set of associated properties. These +are consumed in DXIL backend passes as well as in other usage scenarios such as validation, DXIL reader, etc. -A. Attributes consumed in DXIL backend passes +A. Properties consumed in DXIL backend passes 1. Name of operation (``dxil_op``) 2. A string that documents the operation (``doc``) - This is not strictly necessary but is included @@ -38,7 +38,7 @@ A. Attributes consumed in DXIL backend passes 4. Unique Integer ID (``dxil_opid``) 5. Operation Class signifying the name and function signature of the operation (``dxil_class``). This string is an integral part of the DXIL Op function name and is constructed in - the format ``dx.op..``. Each DXIL Op call target function name + the format ``dx.op..``. Each DXIL Op call target function name is required to conform to this format per existing contract with the driver. 6. List of valid overload types for the operation (``oload_types``). 7. Required DXIL Version with support for the operation. @@ -58,26 +58,26 @@ A. Attributes consumed in DXIL backend passes Motivation ========== -DXIL backend passes depend on various attributes of DXIL Operations. For example, ``DXILOpLowering`` +DXIL backend passes depend on various properties of DXIL Operations. For example, ``DXILOpLowering`` pass will need information such as the DXIL operation an LLVM intrinsic is to be lowered to, -along with valid overload and parameter types etc. The TableGen file - +along with valid overload and argument types etc. The TableGen file - ``llvm/lib/Target/DirectX/DXIL.td`` - is used to represent DXIL Operations -by specifying their attributes listed above. ``DXIL.td`` is designed to be the single source -of reference of DXIL Operations primarily for the implementation of passes in DXIL backend in -``llvm-project`` repo - analogous to ``hctdb.py`` for ``DirectXShadeCompiler`` repo. However, -the current design does not intend to encapsulate various validation rules, present in ``hctdb.py``, -but do not pertain to DXIL Operations. It needs to have a rich representation capabilities that -TableGen backends (such as ``DXILEmitter``) can rely on. Additionally, the DXIL Op specification +by specifying their properties listed above. ``DXIL.td`` is designed to be the single source +of reference of DXIL Operations primarily for the implementation of passes in DXIL backend in +``llvm-project`` repo - analogous to ``hctdb.py`` for ``DirectXShadeCompiler`` repo. However, +the current design does not intend to encapsulate various validation rules, present in ``hctdb.py``, +but do not pertain to DXIL Operations. It needs to have a rich representation capabilities that +TableGen backends (such as ``DXILEmitter``) can rely on. Additionally, the DXIL Op specification should be easy to read and comprehend. This note provides the design of the specification DXIL Ops as TableGen class ``DXILOp`` -by specifying its attributes identified above. +by specifying its properties identified above. DXIL Operation Specification ============================ The DXIL Operation is represented using the TableGen class ``DXILOp``. The DXIL operation -attributes are specified as fields of the ``DXILOp`` class as described below. +properties are specified as fields of the ``DXILOp`` class as described below. 1. Each DXIL Operation is represented as a TableGen record. The name of each of the records signifies operation name. @@ -93,76 +93,81 @@ attributes 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 and argument types of the operation are represented as ``dag``s using the - special markers ``out`` and ``ins``. An overload type, if supported by the operation, is - denoted as the positional type ``dxil_overload_ty`` in the argument or in the result, where - ``dxil_overload_ty`` is defined to be synonymous to ``llvm_any_ty``. +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 dxil_overload_ty = llvm_any_ty + defvar overloadTy = llvm_any_ty + Empty list, ``[]`` represents an operation with no arguments. -7. Valid overload types and shader stages predicated on Shader Model version are specified - as a list of ``Constraint`` records. Representation of ``Constraints`` class is described - a later section. -8. Various attributes of the DXIL Operation that are not predicated on Shader Model version - are represented as a ``dag`` using the special marker ``attrs``. Representation of ``Attributes`` +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. +9. Valid shader stages predicated on DXIL version are specified as a list of + ``Stages`` records. Representation of ``Stages`` class is + described in a later section. +10. Various attributes of the DXIL Operation are represented as a ``list`` of + ``Attributes`` class records. Representation of ``Attributes`` + class is described in a later section. -A DXIL Operation is represented by the following TableGen class by encapsulating the various -TableGen representations of its attributes described above. +Types specific to DXIL +---------------------- + +Type notation used in this document viz., ``Ty`` corresponds to TableGen records for +LLVM types ``llvm__ty``. Apart from ``overloadTy`` described above, ``resRetF32Ty`` is +used to denote resource return type and ``handleTy`` is used to denote handle type. + +Specification of DXIL Operation +================================ + +A DXIL Operation is represented by the following TableGen class that encapsulates the various +TableGen representations of its properties described above. .. code-block:: // Abstraction DXIL Operation - class DXILOp { + class DXILOp { // A short description of the operation string Doc = ""; // Opcode of DXIL Operation - int OpCode = 0; + int OpCode = opcode; // Class of DXIL Operation. - DXILOpClass OpClass = UnknownOpClass; + DXILOpClass OpClass = opclass; // LLVM Intrinsic DXIL Operation maps to Intrinsic LLVMIntrinsic = ?; - // Dag containing the arguments of the op. Default to 0 arguments. - dag arguments = (ins); - - // Results of the op. Default to 0 results. - dag result = (out); - - // List of constraints predicated on Shader Model version - list sm_constraints; + // Result type of the op. + LLVMType result; - // Non-predicated operation attributes - dag attrtibutes = (attrs); - Version DXILVersion = ?; - } - -Constraint Specification -======================== + // List of argument types of the op. Default to 0 arguments. + list arguments = []; -DXIL Operation attributes such as valid overload types and valid shader stages are -predicated on Shader Model version. These are represented as list of constrained -attributes. + // List of valid overload types predicated by DXIL version + list overloads; -Following is the definition of a generic constraint and the associated predicate + // List of valid shader stages predicated by DXIL version + list stages; -.. code-block:: + // List of valid attributes predicated by DXIL version + list attributes = []; + } - // Primitive predicate - class Pred; +Version Specification +===================== - // Generic constraint - class Constraint { - Pred predicate = pred; - } +DXIL version is used to specify various version-dependent operation properties in +place of Shader Model version. -Shader Model version is represented as follows: +A ``Version`` class encapsulating ``Major`` and ``Minor`` version number is defined +as follows: .. code-block:: @@ -172,112 +177,272 @@ Shader Model version is represented as follows: int Minor = minor; } - // Valid Shader model version records - // Definition of Shader Model 6.0 - 6.8 and DXIL Version 1.0 - 1.8 +Concrete representations of valid DXIL versions are defined as follows: + +.. code-block:: + + // Definition of DXIL Version 1.0 - 1.8 foreach i = 0...8 in { - def SM6_#i : Version<6, i>; - def DX1_#i : Version<1, i>; + def DXIL1_#i : Version<1, i>; } -A shader model version predicate class is defined as +Shader Stage Specification +========================== + +Various shader stages such as ``compute``, ``pixel``, ``vertex``, etc., are represented +as follows .. code-block:: - class SMVersion : Pred { - Version SMVersion = ver; - } + // Shader stages + class DXILShaderStage; -A constraint class to represent overload types and shader stages predicated on shader -model version is defined as + def compute : DXILShaderStage; + def pixel : DXILShaderStage; + def vertex : DXILShaderStage; + ... + +Shader Attribute Specification +============================== + +Various operation memory access and boolean attributes such as ``ReadNone``, +``IsWave`` etc., are represented as follows .. code-block:: - class SMVersionConstraints : Constraint { - dag overload_types = oloads; - dag stage_kinds = stages; - } + class DXILAttribute; -The ``dag overload_types`` and ``dag shader_kinds`` use a special markers ``overloads`` -and ``stages``, respectively. + def ReadOnly : DXILOpAttributes; + def ReadNone : DXILOpAttributes; + def IsWave : DXILOpAttributes; + ... -Examples of Constraints ------------------------ +Versioned Property Specification +================================ + +DXIL Operation properties such as valid overload types, shader stages and +attributes are predicated on DXIL version. These are represented as list of +versioned properties. + +Overload Type Specification +--------------------------- -Consider a DXIL Operation that is valid in Shader Model 6.2 and later, +``overloads`` field of ``class DXILOp`` is used to represent valid operation +overloads predicated on DXIL version as list of records of the following class + +.. code-block:: -1. with valid overload types ``half``, ``float``, ``i16`` and ``i32`` -2. is valid for stages ``pixel`` and ``compute`` -3. with valid overload types ``double`` and ``i614`` if Shader Model version 6.3 and later -4. is valid for all stages if Shader Model version 6.3 and later + class Overloads ols> { + Version dxil_version = minver; + list overload_types = ols; + } -This is represented as +Following is an example specification of valid overload types for ``DXIL1_0`` and +``DXIL1_2``. .. code-block:: - [SMVersionConstraints, - (overloads llvm_half_ty, llvm_float_ty, llvm_i16_ty, llvm_i32_ty), - (stages pixel, compute)>, - SMVersionConstraints, - (overloads llvm_half_ty, llvm_float_ty, llvm_double_ty, - llvm_i16_ty, llvm_i32_ty, llvm_i64_ty), - (stages allKinds)>]; + overloads = [ + Overloads, + Overloads + ]; + +An empty list signifies that the operation supports no overload types. -Consider a DXIL operation that is valid in Shader Model version 6.2 and later, -1. with no overload types, i.e., all argument typess and result type are fixed. -2. is valid for all stages. +Stages Specification +-------------------- -This is represented as +``stages`` field of ``class DXILOp`` is used to represent valid operation +stages predicated on DXIL version as list of records of the following class .. code-block:: - [SMVersionConstraints, (overloads), (stages allKinds)>]; + class Stages sts> { + Version dxil_version = minver; + list shader_stages = sts; + } +Following is an example specification of valid stages for ``DXIL1_0``, +``DXIL1_2``, ``DXIL1_4`` and ``DXIL1_6``. + +.. code-block:: + + stages = [ + Stages, + Stages, + Stages, + Stages + ]; + +The following two pseudo stage records in addition to standard shader stages +are defined. + +1. ``all_stages`` signifies that the operation is valid for all stages in the + specified DXIL version and later. +2. ``removed`` signifies removal of support for the operation in the specified + DXIL version and later. + +A non-empty list of supported stages is required to be specified. If an operation +is supported in all DXIL versions and all stages it is required to be specified as + +.. code-block:: + + stages = [Stages]; -Specifying attributes predicated on Shader Model version using the single field -``sm_constraints`` not only allows for all of them to be specified together but -also allows for a single place to specify minimum shader model version that supports -the operation. Thus, a separate fiels is not needed to specify minimum shader model -version. Attribute Specification -======================= +----------------------- -DXIL Operation attributes that are not predicated on any constraint, are represented as -a ``dag`` of Attribute records of the following abstract ``DXILAttributes`` class. +``attributes`` field of ``class DXILOp`` is used to represent valid operation +attributes predicated on DXIL version as list of records of the following class .. code-block:: - class DXILAttributes; + class Attributes attrs> { + MinVersion dxil_version = ver; + list attributes = attrs; + } -Following example records represent memory attributes +Following is an example specification of valid attributes for ``DXIL1_0``. .. code-block:: - def ReadOnly : DXILOpAttributes; - def ReadNone : DXILOpAttributes; + attributes = [Attributes, + Overloads + ]; + +It specifies that the overload types ``halfTy`` and ``floatTy`` are valid for DXIL +version 1.0 and later. It also specifies that ``doubleTy`` is additionally supported +in DXIL version 1.2 and later. + +This provides the flexibility to specify properties independent of other +versioned specifications in the list. + + +DXIL Operation Specification Examples +===================================== + +Following examples illustrate the specification of some of the DXIL Ops. + +``Sin`` operation - an operation valid in all DXIL versions and all stages +and has valid overload types predicated on DXIL version. + +.. code-block:: + + def Sin : DXILOp<13, unary> { + let Doc = "Returns sine(theta) for theta in radians."; let LLVMIntrinsic = int_sin; - let arguments = (ins LLVMMatchType<0>); - let result = (out dxil_overload_ty); - let sm_constraints = [SMVersionConstraints, - (overloads llvm_half_ty, llvm_float_ty), - (stages allKinds)>]; - let attributes = (attrs ReadNone); - let DXILVersion = DX1_0; + let result = overloadTy; + let arguments = [overloadTy]; + let overloads = [Overloads]; + let stages = [Stages]; + let attributes = [Attributes]; } +``FlattenedThreadIdInGroup`` - an operation with no arguments, no +overload types, and valid stages and attributes predicated by DXIL Version. + +.. code-block:: + + 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 stages = [Stages]; + let attributes = [Attributes]; + } + +``RawBufferStore`` - an operation with ``void`` return type, valid overload types +predicated by DXIL Version and valid in all DXIL versions and stages. + +.. code-block:: + + def RawBufferStore : DXILOp<140, rawBufferStore> { + let Doc = "Writes to a RWByteAddressBuffer or RWStructuredBuffer."; + let result = voidTy; + let arguments = [dxil_resource_ty, i32Ty, i32Ty, overloadTy, + overloadTy, overloadTy, overloadTy, i8Ty, i32Ty]; + let overloads = [ + Overloads, + Overloads,[halfTy, floatTy, doubleTy, + i16Ty, i32Ty, i64Ty]> + ]; + let stages = [Stages]; + let attributes = [Attributes]; + } + +``DerivCoarseX`` - an operation with no overload types and stages predicated +by DXIL Version. + +.. code-block:: + + def DerivCoarseX : DXILOp<83, unary> { + let doc = "Computes the rate of change per stamp in x direction."; + let LLVMIntrinsic = int_dx_ddx; + let result = overloadTy; + let arguments = [overloadTy]; + let stages = [ + Stages, + Stages + ]; + let attributes = [Attributes]; + } + +``CreateHandle`` - an operation with no overload types, no associated ``LLVMIntrinsic`` +and stages predicated by DXIL Version. + +.. code-block:: + + def CreateHandle : DXILOp<57, createHandle> { + let doc = "Creates the handle to a resource"; + let result = i32Ty; + let arguments = [i8Ty, i32Ty, i32Ty, i1Ty]; + let stages = [ + Stages, + Stages]; + } + +``Sample`` - an operation with valid overload types, stages and attributes +predicated by DXIL version. + +.. code-block:: + + def Sample : DXILOp<60, sample> { + let Doc = "Samples a texture"; + let LLVMIntrinsic = int_dx_sample; + let result = resRetF32Ty; + let arguments = [handleTy, handleTy, floatTy, floatTy, floatTy, floatTy, + i32Ty, i32Ty, i32Ty, floatTy]; + let overloads = [Overloads]; + let stages = [ + Stages, + Stages + ]; + let attributes = [Attributes]; + } + Summary =======