[llvm] 6777c34 - [DXIL][Doc] Update specification of TableGen DXIL properties (#99055)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 22 13:23:31 PDT 2024
Author: S. Bharadwaj Yadavalli
Date: 2024-07-22T16:23:27-04:00
New Revision: 6777c3400708abbd607e7c167f73922eb0d807dc
URL: https://github.com/llvm/llvm-project/commit/6777c3400708abbd607e7c167f73922eb0d807dc
DIFF: https://github.com/llvm/llvm-project/commit/6777c3400708abbd607e7c167f73922eb0d807dc.diff
LOG: [DXIL][Doc] Update specification of TableGen DXIL properties (#99055)
Update the specification of various DXIL Operation properties that
are predicated by DXIL version.
Added:
Modified:
llvm/docs/DirectX/DXILOpTableGenDesign.rst
Removed:
################################################################################
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.<class-name>.<overload-type>``. Each DXIL Op call target function name
+ the format ``dx.op.<class-name>.<overload-type>``. 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., ``<size>Ty`` corresponds to TableGen records for
+LLVM types ``llvm_<size>_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<int opcode, DXILOpClass opclass> {
// 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<SMVersionConstraints> 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<LLVMType> 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> overloads;
-Following is the definition of a generic constraint and the associated predicate
+ // List of valid shader stages predicated by DXIL version
+ list<Stages> stages;
-.. code-block::
+ // List of valid attributes predicated by DXIL version
+ list<Attributes> attributes = [];
+ }
- // Primitive predicate
- class Pred;
+Version Specification
+=====================
- // Generic constraint
- class Constraint<Pred pred> {
- 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<Version ver> : 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<SMVersion smver, dag oloads, dag stages> : Constraint<smver> {
- 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<Version minver, list<LLVMType> ols> {
+ Version dxil_version = minver;
+ list<LLVMType> 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<SMVersion<SM6_2>,
- (overloads llvm_half_ty, llvm_float_ty, llvm_i16_ty, llvm_i32_ty),
- (stages pixel, compute)>,
- SMVersionConstraints<SMVersion<SM6_3>,
- (overloads llvm_half_ty, llvm_float_ty, llvm_double_ty,
- llvm_i16_ty, llvm_i32_ty, llvm_i64_ty),
- (stages allKinds)>];
+ overloads = [
+ Overloads<DXIL1_0, [halfTy, floatTy]>,
+ Overloads<DXIL1_2, [halfTy, floatTy, doubleTy]>
+ ];
+
+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<SMVersion<SM6_2>, (overloads), (stages allKinds)>];
+ class Stages<Version minver, list<DXILShaderStage> sts> {
+ Version dxil_version = minver;
+ list<DXILShaderStage> 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<DXIL1_0, [compute, pixel]>,
+ Stages<DXIL1_2, [compute, pixel, mesh]>,
+ Stages<DXIL1_4, [all_stages]>,
+ Stages<DXIL1_6, [removed]>
+ ];
+
+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<DXIL1_0, [all_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<MinVersion minver, list<DXILAttribute> attrs> {
+ MinVersion dxil_version = ver;
+ list<DXILAttribute> 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<DXIL1_0, [ReadNone]];
+
+A null list of ``attributes`` signifies no operation attributes.
-DXIL Operation Specification Example
-====================================
-Following illustrates the specification of the DXIL Op ``Sin``
+Interpretation of Multiple Versioned Properties
+-----------------------------------------------
+
+Each of the versioned properties states that the specified overload type, stage or
+attribute records are valid for the predicated DXIL version. Only
+the properties corresponding to latest minimal DXIL version are applicable.
+Note as in the above example, any overload types, stages or attributes,
+that remain valid in a later DXIL version need to be specified in full.
+For example, consider the following specification of valid overload types:
.. code-block::
- def Sin : DXILOp {
- let Doc ="Returns sine(theta) for theta in radians.";
- let OpCode = 13;
- let OpClass = unary;
+ overloads = [
+ Overloads<DXIL1_0, [halfTy, floatTy]>,
+ Overloads<DXIL1_2, [halfTy, floatTy, doubleTy]>
+ ];
+
+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<SMVersion<SM6_0>,
- (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<DXIL1_0, [halfTy, floatTy]>];
+ let stages = [Stages<DXIL1_0, [all_stages]>];
+ let attributes = [Attributes<DXIL1_0, [ReadNone]>];
}
+``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<DXIL1_0, [compute, mesh, amplification, node]>];
+ let attributes = [Attributes<DXIL1_0, [ReadNone]>];
+ }
+
+``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<DXIL1_2, [halfTy, floatTy, i16Ty, i32Ty]>,
+ Overloads<DXIL1_3>,[halfTy, floatTy, doubleTy,
+ i16Ty, i32Ty, i64Ty]>
+ ];
+ let stages = [Stages<DXIL1_2, all_stages>];
+ let attributes = [Attributes<DXIL1_0, [ReadOnly]>];
+ }
+
+``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<DXIL1_0, [library, pixel]>,
+ Stages<DXIL1_6, [library, pixel, amplification, compute, mesh]>
+ ];
+ let attributes = [Attributes<DXIL1_0, [ReadNone]>];
+ }
+
+``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<DXIL1_0, [all_stages]>,
+ Stages<DXIL1_6, [removed]
+ ];
+ let attributes = [Attributes<DXIL1_0, [ReadOnly]>];
+ }
+
+``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<DXIL1_0, [halfTy, floatTy, i16Ty, i32Ty]>];
+ let stages = [
+ Stages<DXIL1_0, [library, pixel]>,
+ Stages<DXIL1_6, [library, pixel, amplification, compute, mesh]>
+ ];
+ let attributes = [Attributes<DXIL1_0, [ReadOnly]>];
+ }
+
Summary
=======
More information about the llvm-commits
mailing list