Skip to content

Commit 51732aa

Browse files
committed
[DOC] Simplify design for POD spec constants
Removed `__sycl_getCompositeSpecConstantValue` intrinsic, because we can check if specialization constant is a composite type by looking at return type of `__sycl_getSpecConstantValue`. This also allows us to avoid any changes in `cl::sycl::ONEAPI::experimental::spec_constant::get` method. Renamed `__spirvCompositeSpecConstant` to `__spirv_SpecConstantComposite` to better match SPIR-V friendly IR representaiton, which is aligned with opcode names from SPIR-V spec. Changed logic of generating `__spirv_SpecConstantComposite`: instead of getting list of `SpecID` for each composite member it now accepts vector of actual members, which might be another composits, undefs or regular constants. This change was done to align this intrinsic with corresponding opcode prototype to make its handling more universal and useful for the upstream translator project. Therefore, completely removed some sections which are outdated assuming new approach.
1 parent 47eb184 commit 51732aa

File tree

1 file changed

+26
-63
lines changed

1 file changed

+26
-63
lines changed

sycl/doc/SpecializationConstants.md

Lines changed: 26 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -200,39 +200,41 @@ and the user says
200200
- The SpecConstants pass in the post-link will have the following IR as input (`sret` conversion is omitted for clarity):
201201
202202
```
203-
%spec_const = call %struct.POD __sycl_getCompositeSpecConstantValue<POD type mangling> ("MyConst_mangled")
204-
```
203+
%struct.POD = type { [2 x %struct.A], i32 }
204+
%struct.A = type { i32, float }
205205

206-
where `__sycl_getCompositeSpecConstantValue` is a new "intrinsic"
207-
(in addition to `__sycl_getSpecConstantValue`) recognized by SpecConstants pass,
208-
which creates a value of a composite (of non-primitive type) specialization constant.
209-
It does not need a default value, because its default value consists of default
210-
valued of its leaf specialization constants (see below).
206+
%spec_const = call %struct.POD __sycl_getSpecConstantValue<POD type mangling> ("MyConst_mangled")
207+
```
211208
212-
- after spec constant enumeration (symbolic -\> int ID translation), the SpecConstants pass
213-
will handle the `__sycl_getCompositeSpecConstantValue`. Given the knowledge of the composite
214-
specialization constant's type (`%struct.POD`), the pass will traverse its leaf
215-
fields and generate 5 "primitive" spec constants using already existing SPIR-V intrinsic:
209+
Based on the fact that `__sycl_getSpecConstantValue` returns `llvm::StructType`,
210+
it will be replaced with a set of `__spirv_SpecConstant` calls for each member
211+
of its return type plus one `__spirv_SpecConstantComposite` to gather members
212+
back into a single composite. If any composite member is another composite, then
213+
it will be also represented by number of `__spirv_SpecConstant` plus one
214+
`__spirv_SpecConstantComposite`:
216215
217216
```
218-
%gold_POD_a0x = call i32 __spirv_SpecConstant(i32 10, i32 0)
219-
%gold_POD_a0y = call float __spirv_SpecConstant(i32 11, float 0)
220-
%gold_POD_a1x = call i32 __spirv_SpecConstant(i32 12, i32 0)
221-
%gold_POD_a1y = call float __spirv_SpecConstant(i32 13, float 0)
217+
%gold_POD_A0_x = call i32 __spirv_SpecConstant(i32 10, i32 0)
218+
%gold_POD_A0_y = call float __spirv_SpecConstant(i32 11, float 0)
219+
220+
%gold_POD_A0 = call %struct.A __spirv_SpecConstantComposite(i32 %gold_POD_A0_x, float %gold_POD_A0_y)
221+
222+
%gold_POD_A1_x = call i32 __spirv_SpecConstant(i32 12, i32 0)
223+
%gold_POD_A1_y = call float __spirv_SpecConstant(i32 13, float 0)
224+
225+
%gold_POD_A1 = call %struct.A __spirv_SpecConstantComposite(i32 %gold_POD_A1_x, float %gold_POD_A1_y)
226+
227+
%gold_POD_A = call [2 x %struct.A] __spirv_SpecConstantComposite(%struct.A %gold_POD_A0, %struct.A %gold_POD_A1)
222228
%gold_POD_b = call i32 __spirv_SpecConstant(i32 14, i32 0)
223-
```
224229

225-
And 1 "composite"
230+
%gold = call %struct.POD __spirv_SpecConstantComposite([2 x %struct.A] %gold_POD_A, i32 %gold_POD_b)
226231

227-
```
228-
%gold_POD = call %struct.POD __spirvCompositeSpecConstant<POD type mangling>(i32 10, i32 11, i32 12, i32 13, i32 14)
229232
```
230233
231-
where `__spirvCompositeSpecConstant<POD type mangling>` is a new SPIR-V intrinsic which
232-
represents creation of a composite specialization constant. Its arguments are spec
233-
constant IDs corresponding to the leaf fields of the POD type of the constant.
234-
Spec ID for the composite spec constant is not needed, as runtime will never use it - it will use IDs of the leaves instead.
235-
Yet, the SPIR-V specification does not allow `SpecID` decoration for composite spec constants.
234+
Spec ID for the composite spec constant is not needed, as runtime will never use
235+
it - it will use IDs of the leaves instead.
236+
Yet, the SPIR-V specification does not allow `SpecID` decoration for composite
237+
spec constants, because its defined by its members instead.
236238
237239
##### The post-link tool changes
238240
@@ -248,45 +250,6 @@ referenced by its symbolic ID. For example:
248250
MyConst_mangled [10,int,0,4],[11,float,4,4],[12,int,8,4],[13,float,12,4],[14,int,16,4]
249251
```
250252
251-
#### LLVMIR-\>SPIR-V translator
252-
253-
The translator aims to create the following code (pseudo-code)
254-
255-
```
256-
%gold_POD_a0x = OpSpecConstant(0) [SpecId = 10]
257-
%gold_POD_a0y = OpSpecConstant(0.0f) [SpecId = 11]
258-
%gold_POD_a1x = OpSpecConstant(0) [SpecId = 12]
259-
%gold_POD_a1y = OpSpecConstant(0.0f) [SpecId = 13]
260-
%gold_POD_b = OpSpecConstant(0) [SpecId = 14]
261-
262-
%gold_POD_a0 = OpSpecConstantComposite(
263-
%gold_POD_a0x // gold.a[0].x
264-
%gold_POD_a0y // gold.a[0].y
265-
)
266-
267-
%gold_POD_a1 = OpSpecConstantComposite(
268-
%gold_POD_a1x // gold.a[1].x
269-
%gold_POD_a1y // gold.a[1].y
270-
)
271-
272-
%gold_POD = OpSpecConstantComposite(
273-
%gold_POD_a0,
274-
%gold_POD_a1,
275-
%gold_POD_b // gold.b
276-
}
277-
```
278-
279-
- First, `OpSpecConstant` instructions are created using already existing mechanism for
280-
primitive spec constants.
281-
- Then the translator will handle `__spirvCompositeSpecConstant*` intrinsic.
282-
It will recursively traverse the spec constant type structure in parallel with
283-
the argument list - which is a list of primitive spec constant SpecIds.
284-
When traversing, it will create all the intermediate OpSpecConstantComposite
285-
instructions as well as the root one (`%gold_POD`) using simple depth-first tree
286-
traversal with stack. This requires mapping from SpecId decoration number to
287-
\<id\> of the corresponding OpSpecConstant instruction, but this should be pretty
288-
straightforward.
289-
290253
#### SYCL runtime
291254
292255
First, when the runtime loads a binary it gets access to specialization

0 commit comments

Comments
 (0)