@@ -19,207 +19,164 @@ DXIL Operations are represented in one of the following `two ways
19
19
#. Using LLVM instructions
20
20
#. Using LLVM External functions. These are represented in LLVM IR as follows:
21
21
22
- * "Standard" LLVM intrinsics (e.g., ``llvm.sin.* ``) and
23
- * HLSL intrinsics (defined as LLVM intrinsics in ``llvm/include/llvm/IR/IntrinsicsDirectX.td ``, e.g., ``llvm.dx.* ``)
24
-
25
- These are collectively referred to as `LLVM Intrinsics ` in this note.
26
-
27
- DXIL Ops, as currently represented in ``hctdb.py `` have the following attributes
28
-
29
- #. ``name `` - A short, unique name
30
- #. ``llvm_id `` - ID of LLVM instruction. This is just an arbitrary, yet fixed, number that indicates LLVM's ``CallInst `` for all LLVM intrinsics
31
- #. ``llvm_name `` - String name of LLVM instruction type
32
- #. ``is_dxil_op `` - A bool indicating whether this is a call into a built-in DXIL function
33
- #. ``dxil_op `` - String name of DXIL operation
34
- #. ``dxil_opid `` - ID of DXIL operation
35
- #. ``dxil_class `` - String name of the opcode class
36
- #. ``category `` - String classification for this instruction
37
- #. ``doc `` - String documentation description of this instruction
38
- #. ``remarks `` - String long-form remarks on this instruction
39
- #. ``ops `` - List of operands that this instruction takes
40
- #. ``is_allowed `` - Bool indicating whether this instruction is allowed in a DXIL program
41
- #. ``oload_types `` - String denoting overload types if applicable (e.g., "hf", "iwl")
42
- #. ``fn_attr `` - Attribute shorthand strings: rn=does not access memory,ro=only reads from memory,
43
- #. ``is_deriv `` - Bool indicating whether this is some kind of derivative
44
- #. ``is_gradient `` - Bool indicating whether this requires a gradient calculation
45
- #. ``is_feedback `` - Bool indicating whether this is a sampler feedback op
46
- #. ``is_wave `` - Bool indicating whether this requires in-wave, cross-lane functionality
47
- #. ``requires_uniform_inputs `` - Bool indicating whether this operation requires that all of its inputs are uniform across the wave
48
- #. ``is_barrier `` - Bool indicating whether this is a barrier operation
49
- #. ``shader_stages `` - shader stages to which this applies, empty for all.
50
- #. ``shader_model `` - minimum shader model required (e.g., 6, 0)
51
- #. ``inst_helper_prefix `` - None
52
- #. ``fully_qualified_name_prefix `` - Constant string ``"hlsl::OP::OpCode" ``
53
- #. ``is_dxil_op `` - Bool that evaluates (dxil_op != "") indicating whether this is a DXIL operation
54
- #. ``is_reserved `` - Bool that evaluates (dxil_class == "Reserved")
55
- #. ``shader_model_translated `` - minimum shader model required with translation by linker
56
- #. ``props `` - extra properties
57
-
58
- Core DXIL Operation information is encapsulated in ``utils/hct/hctdb.py ``. Additional
59
- refinements of this information, such as supported overload types specific to
60
- Shader Model version, is embedded in various other source locations in
61
- `DirectXShaderCompiler <https://github.com/microsoft/DirectXShaderCompiler >`_
62
- repo. Additional conditions that refine the DXIL Op properties are also encoded
63
- in the DXIL Validator component.
22
+ * "Standard" LLVM intrinsics (e.g., ``llvm.sin.* ``) and
23
+ * HLSL intrinsics (defined as LLVM intrinsics in ``llvm/include/llvm/IR/IntrinsicsDirectX.td ``, e.g., ``llvm.dx.* ``)
24
+
25
+ These are collectively referred to as `LLVM Intrinsics ` in this note.
26
+
27
+ Following is the complete list of properties of DXIL Ops with the corresponding field name
28
+ as used in ``hctdb.py ``, if one exists. A DXIL Op is represented by a set of associated properties
29
+
30
+ 1. Name of operation (``dxil_op ``)
31
+ 2. The generic or HLSL-specific intrinsic that maps to the operation (``llvm_name ``).
32
+ 3. Unique Integer ID (``dxil_opid ``)
33
+ 4. Operation Class signifying the name and function signature of the operation (``dxil_class ``).
34
+ This string is an integral part of the DXIL Op function name and is constructed in
35
+ the format ``dx.op.<class-name>.<overload-type> ``. The DXIL validator checks for any
36
+ deviation from this for each of the DXIL Op call.
37
+
38
+ 5. List of valid overload types for the operation (``oload_types ``).
39
+ 6. Required minimum Shader Model version with support for the operation. (``shader_model ``).
40
+ 7. Required minimum DXIL version with support for the operation.
41
+ 8. Minimum shader model required with translation by linker (``shader_model_translated ``)
42
+ 9. List of shader stages the operation is applicable to (``shader_stages ``); empty if applicable to all stages.
43
+ 10. Memory access attributes of the operation (``fn_attr ``).
44
+ 11. Boolean attributes of operation to indicate if it
45
+
46
+ * is some kind of a derivative (``is_derivative ``)
47
+ * requires gradient calculation (``is_gradient ``)
48
+ * is a sampler feedback (``is_feedback ``)
49
+ * requires in-wave, cross-lane functionality (``is_wave ``)
50
+ * requires that all of its inputs are uniform across the wave (``requires_uniform_inputs ``).
51
+ * is a barrier operation (``is_barrier ``).
52
+
53
+ 12. A string that documents the operation (``doc ``)
64
54
65
55
Motivation
66
56
==========
67
57
68
- ``DXILLowering `` pass needs to lower the LLVM intrinsics. TableGen file -
69
- ``llvm/lib/Target/DirectX/DXIL.td `` - is used to specify the properties of DXIL
70
- Ops including the mapping of each of them to LLVM intrinsics they correspond to,
71
- if any. This purpose is served by ``utils/hct/hctdb.py `` in ``DirectXShaderCompiler ``
72
- repo. Analogously, ``DXIL.td `` is planned to be the single source of reference
73
- for the properties and LLVM intrinsic mapping of DXIL Ops for DXIL backend
74
- implementation in ``llvm-project `` repo. Additionally, the refinements of DXIL Op
75
- properties based on aspects such as target Shader Model version, Shader kind (viz.,
76
- Compute, Pixel, Vertex etc) should also be represented in TableGen specification
77
- of DXIL Ops - as much as possible. This will allow generation of valid DXIL code
78
- in all passes and potentially not require (or reduce the complexity of) a post-compile
79
- validation step that ensures valid DXIL binary.
80
-
81
- As a result, specification in ``DXIL.td `` needs to have a rich representation
82
- abilities that TableGen backends (such as ``DXILEmitter ``) can rely on. The DXIL
83
- Op specification should be declarative - as much as possible - making it
84
- easy to comprehend and amenable to specification of constraints that refine
85
- DXIL Op properties.
86
-
87
- .. _DXIL Operation Attributes :
88
-
89
- DXIL Operation Attributes
90
- =========================
91
-
92
- Distilling the essential attributes of DXIL Op from the above, following
93
- attributes form the core of its specification.
94
-
95
- #. ``dxil_opid `` or ``OpCode ``
96
- #. ``dxil_class `` or ``OpClass `` - this string is an integral part of the DXIL Op
97
- function name and is constructed in the format ``dx.op.<class-name>.<overload-type> ``.
98
- The DXIL validator checks for any deviation from this for each of the DXIL Op call.
99
- #. ``ops `` - list of operands encapsulating the index and valid (fixed or overload) types
100
- #. ``oload_types `` - Valid overload types of the DXIL op
101
- #. Rest of the attributes represented using ``is_* `` booleans along with
102
- ``shader_model_translated `` and ``shader_stages ``
103
-
104
- Each of the LLVM intrinsics maps to an function represented by a call to an
105
- external function of the form ``dx.op.<class-name>.<overload-type> `` as noted above.
106
-
107
- TableGen Specification
108
- ======================
109
-
110
- Shader Model
111
- ^^^^^^^^^^^^
112
-
113
- DirectX Shader Models are distinguished by their ``major.minor `` number.
114
- This is represented by the following TableGen class.
58
+ DXIL backend passes depend on the knowledge of various properties of DXIL Operations.
59
+ For example, ``DXILLowering `` pass will need information such as the DXIL operation an
60
+ LLVM intrinsic is to be lowered to, along with valid overload and parameter types etc.
61
+ TableGen file - ``llvm/lib/Target/DirectX/DXIL.td `` - is used to represent DXIL Operations
62
+ by specifying their properties listed above. ``DXIL.td `` is designed to be the single source
63
+ of reference of DXIL Operations for DXIL backend implementation in ``llvm-project `` repo -
64
+ analogous to ``hctdb.py `` for ``DirectXShadeCompiler `` repo. It needs to have a rich
65
+ representation capabilities that TableGen backends (such as ``DXILEmitter ``) can rely on.
66
+ Additionally, the DXIL Op specification should be easy to read and comprehend.
115
67
116
- .. code-block ::
68
+ Design
69
+ ======
117
70
118
- class DXILShaderModel<int major, int minor> {
119
- int Major = major;
120
- int Minor = minor;
121
- }
71
+ 1. Each DXIL Operation is represented as a TableGen record. The name of each of the records
72
+ signifies operation name.
73
+ 2. The LLVM Intrinsic that maps to the operation is represented using ``Intrinsic::* ``.
74
+ 3. The unique operation id is represented by an integer.
75
+ 4. DXIL Operation Class is represented as follows
122
76
123
- Each of the valid shader models is defined as TableGen records. For
124
- example following is the definition of SM 6.0 and SM 6.2,
77
+ .. code-block ::
125
78
126
- .. code-block ::
79
+ // Abstraction of DXIL Operation class.
80
+ // It encapsulates an associated function signature viz.,
81
+ // returnTy(param1Ty, param2Ty, ...) represented as a list of LLVMTypes.
82
+ // DXIL Ops that belong to a DXILOpClass record the signature of that DXILOpClass
127
83
128
- // Shader Model 6.x
129
- def SM6_0 : DXILShaderModel<6, 0> ;
130
- def SM6_2 : DXILShaderModel<6, 2>;
84
+ class DXILOpClass<list<LLVMType> OpSig> {
85
+ list<LLVMType> OpSignature = OpSig ;
86
+ }
131
87
132
- DXIL Class
133
- ^^^^^^^^^^
88
+ Concrete operation classes, such as ``unary `` are defined inheriting from ``DXILOpClass ``.
89
+ 5. Valid overload types are represented as a list of ``LLVMType `` s.
90
+ 6. Concrete records of Shader Model version and DXIL versions and are defined
91
+ by inheriting from the class
134
92
135
- Each DXIL Op belongs to a class represented by ``dxil_class `` field value. A
136
- DXIL class represents DXIL Ops with the same function prototype (or signature).
137
- This is represented using the following TableGen class.
93
+ .. code-block ::
138
94
139
- .. code-block ::
95
+ // Abstract class to represent major and minor version values
96
+ class Version<int major, int minor> {
97
+ int Major = major;
98
+ int Minor = minor;
99
+ }
140
100
141
- class DXILOpClass<list<LLVMType> OpSig> {
142
- list<LLVMType> OpSignature = OpSig;
143
- }
101
+ 7. Shader stages for which the operation is applicable are represented as a list of
102
+ concrete records that inherit from the Class
144
103
145
- Each of the valid classes is represented by a concrete TableGen record.
146
- For example, following is the definition of the ``unary `` class
104
+ .. code-block ::
147
105
148
- .. code-block ::
106
+ class ShaderStage;
149
107
150
- def unary : DXILOpClass<[llvm_any_ty, LLVMMatch<0>]>;
151
108
109
+ 8. All remaining properties of the operation are represented as a list as of concrete records
110
+ that inherit from the class
152
111
153
- Overload Types
154
- ^^^^^^^^^^^^^^
112
+ .. code-block ::
155
113
156
- Each DXIL Op has a set of valid overload types denoted by ``oload_types ``.
157
- Valid overload types of a DXIL OP are represented as a list. However, overload
158
- types supported by DXIL Ops may vary depending on minimum target shader model
159
- version. So, the list of supported overload types are tagged with the minimum
160
- shader model in which they are valid for the DXIL Op being specified.
161
- Following TableGen class is defined to encapsulate such as representation.
114
+ class OpAttributes;
162
115
163
- .. code-block ::
116
+ - memory access - ``ReadNone ``, ``ReadNone ``
117
+ - ``IsDerivative ``, ``IsGradient ``, ``IsFeedback ``, ``IsWave ``, ``NeedsUniformInputs ``, ``IsBarrier ``
164
118
165
- class DXILOpOverload<DXILShaderModel minsm, list<LLVMType> overloads> {
166
- DXILShaderModel ShaderModel = minsm;
167
- list<LLVMType> OpOverloads = overloads;
168
- }
119
+ 9. A documentation string for the operation.
169
120
170
- Specification of DXIL Operation
171
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
172
121
173
- Specification of DXIL Op is abstracted using the following TableGen class to
174
- represent the core attributes outlined in ` DXIL Operation Attributes `_ section .
122
+ A DXIL Operation is represented by the following TableGne class by encapsulating the various
123
+ TableGen representations of its properties described above .
175
124
176
125
.. code-block ::
177
126
178
- // Abstraction DXIL Operation to LLVM intrinsic
179
- class DXILOpMappingBase {
180
- int OpCode = 0; // Opcode of DXIL Operation
181
- DXILOpClass OpClass = UnknownOpClass;// Class of DXIL Operation.
182
- Intrinsic LLVMIntrinsic = ?; // LLVM Intrinsic DXIL Operation maps to
183
- list<DXILOpOverload> OpOverloadTypes = ?; // Valid overload type
184
- // of DXIL Operation
185
- string Doc = ""; // A short description of the operation
127
+ // Abstraction DXIL Operation
128
+ class DXILOpPropertiesBase {
129
+ int OpCode = 0; // Opcode of DXIL Operation
130
+ DXILOpClass OpClass = UnknownOpClass; // Class of DXIL Operation.
131
+ Intrinsic LLVMIntrinsic = ?; // LLVM Intrinsic DXIL Operation maps to
132
+ list<LLVMType> OpOverloadTypes = ?; // Valid overload type
133
+ // of DXIL Operation
134
+ Version SMVer = ?; // Min Shader Model version
135
+ Version SMVerLinker = ?; // Min Shader Model required for linking
136
+ Version DXILVer = ?; // Min DXIL version
137
+ list<ShaderStage> ShaderStages = ?; // List of applicable shader stages
138
+ list<OpAttributes> OpAttribs = ?; // Operation attributes
139
+ string Doc = ""; // A short description of the operation
186
140
}
187
141
188
- Following is a convenience TableGen class that inherits from ``DXILOpMappingBase ``
189
- with templatized parameters. It is used to define various DXIL Ops.
190
142
191
- .. code-block ::
143
+ The following convenience class is used to demonstrate the definitions of a couple of
144
+ operations:
192
145
193
- class DXILOpMapping<int opCode,
146
+ .. code-block ::
147
+
148
+ class DXILOpProperties<int opCode,
194
149
Intrinsic intrinsic,
195
- list<DXILOpOverload > overloadTypes,
196
- string doc> : DXILOpMappingBase {
197
- int OpCode = opCode;
198
- Intrinsic LLVMIntrinsic = intrinsic;
199
- list<DXILOpOverload > OpOverloadTypes = overloadTypes;
200
- string Doc = doc;
201
- }
150
+ list<LLVMType > overloadTypes,
151
+ string doc> : DXILOpPropertiesBase {
152
+ int OpCode = opCode;
153
+ Intrinsic LLVMIntrinsic = intrinsic;
154
+ list<LLVMType > OpOverloadTypes = overloadTypes;
155
+ string Doc = doc;
156
+ }
202
157
203
- The DXIL Op `` Sin `` is defined as follows :
158
+ Additionally, following definition of `` unary `` class is also used :
204
159
205
160
.. code-block ::
206
161
207
- let OpClass = unary in
208
- def Sin : DXILOpMapping<13, int_sin,
209
- [DXILOpOverload<SM6_3, [llvm_half_ty, llvm_float_ty]>,
210
- DXILOpOverload<SM6_0, [llvm_float_ty]>],
211
- "Returns sine(theta) for theta in radians.">;
162
+ def unary : DXILOpClass<[llvm_any_ty, LLVMMatchType<0>]>;
212
163
164
+ Following is the definition of ``Sin `` and ``Cos ``
213
165
214
- Note that validity of overload type ``float `` in SM 6.0 and later, and
215
- that of ``half `` and ``float `` in SM 6.2 and later, is specified.
166
+ .. code-block ::
167
+
168
+ let OpClass = unary in {
169
+ def Cos : DXILOpProperties<12, int_cos, [llvm_half_ty, llvm_float_ty],
170
+ "Returns cosine(theta) for theta in radians.">;
171
+ def Sin : DXILOpProperties<13, int_sin, [llvm_half_ty, llvm_float_ty],
172
+ "Returns sine(theta) for theta in radians.">;
173
+ }
216
174
217
175
Summary
218
176
=======
219
177
220
- This note describes design and implementation of a TableGen representation of
221
- DXIL Ops in ``DXIL.td ``. ``DXIL.td `` is intended to (a) serve as a single source
222
- of reference for TableGen backends (such as ``DXILEmitter ``- specific to DXIL
223
- backend), (b) have an accurate and rich specification including the ability to
224
- represent refinement constraints, and (c) be declarative as much as possible for
225
- readability and maintainability.
178
+ This note discusses the design of TableGen specification of DXIL Ops in ``DXIL.td ``
179
+ that is intended to serve as a single source of reference for TableGen
180
+ backends (such as ``DXILEmitter `` - specific to DXIL backend), have an accurate
181
+ and rich specification, be readable and maintainable.
182
+
0 commit comments