@@ -200,39 +200,41 @@ and the user says
200
200
- The SpecConstants pass in the post-link will have the following IR as input (`sret` conversion is omitted for clarity):
201
201
202
202
```
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 }
205
205
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
+ ```
211
208
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`:
216
215
217
216
```
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)
222
228
%gold_POD_b = call i32 __ spirv_SpecConstant(i32 14, i32 0)
223
- ```
224
229
225
- And 1 "composite"
230
+ %gold = call %struct.POD __ spirv_SpecConstantComposite( [ 2 x %struct.A ] %gold_POD_A, i32 %gold_POD_b)
226
231
227
- ```
228
- %gold_POD = call %struct.POD __ spirvCompositeSpecConstant<POD type mangling >(i32 10, i32 11, i32 12, i32 13, i32 14)
229
232
```
230
233
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.
236
238
237
239
##### The post-link tool changes
238
240
@@ -248,45 +250,6 @@ referenced by its symbolic ID. For example:
248
250
MyConst_mangled [ 10,int,0,4] ,[ 11,float,4,4] ,[ 12,int,8,4] ,[ 13,float,12,4] ,[ 14,int,16,4]
249
251
```
250
252
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
-
290
253
#### SYCL runtime
291
254
292
255
First, when the runtime loads a binary it gets access to specialization
0 commit comments