1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "vtn_private.h"
25 #include "spirv_info.h"
26 #include "nir/nir_vla.h"
27 #include "util/u_debug.h"
28
29 static unsigned
glsl_type_count_function_params(const struct glsl_type * type)30 glsl_type_count_function_params(const struct glsl_type *type)
31 {
32 if (glsl_type_is_vector_or_scalar(type)) {
33 return 1;
34 } else if (glsl_type_is_array_or_matrix(type)) {
35 return glsl_get_length(type) *
36 glsl_type_count_function_params(glsl_get_array_element(type));
37 } else {
38 assert(glsl_type_is_struct_or_ifc(type));
39 unsigned count = 0;
40 unsigned elems = glsl_get_length(type);
41 for (unsigned i = 0; i < elems; i++) {
42 const struct glsl_type *elem_type = glsl_get_struct_field(type, i);
43 count += glsl_type_count_function_params(elem_type);
44 }
45 return count;
46 }
47 }
48
49 static void
glsl_type_add_to_function_params(const struct glsl_type * type,nir_function * func,unsigned * param_idx)50 glsl_type_add_to_function_params(const struct glsl_type *type,
51 nir_function *func,
52 unsigned *param_idx)
53 {
54 if (glsl_type_is_vector_or_scalar(type)) {
55 func->params[(*param_idx)++] = (nir_parameter) {
56 .num_components = glsl_get_vector_elements(type),
57 .bit_size = glsl_get_bit_size(type),
58 };
59 } else if (glsl_type_is_array_or_matrix(type)) {
60 unsigned elems = glsl_get_length(type);
61 const struct glsl_type *elem_type = glsl_get_array_element(type);
62 for (unsigned i = 0; i < elems; i++)
63 glsl_type_add_to_function_params(elem_type,func, param_idx);
64 } else {
65 assert(glsl_type_is_struct_or_ifc(type));
66 unsigned elems = glsl_get_length(type);
67 for (unsigned i = 0; i < elems; i++) {
68 const struct glsl_type *elem_type = glsl_get_struct_field(type, i);
69 glsl_type_add_to_function_params(elem_type, func, param_idx);
70 }
71 }
72 }
73
74 static void
vtn_ssa_value_add_to_call_params(struct vtn_builder * b,struct vtn_ssa_value * value,nir_call_instr * call,unsigned * param_idx)75 vtn_ssa_value_add_to_call_params(struct vtn_builder *b,
76 struct vtn_ssa_value *value,
77 nir_call_instr *call,
78 unsigned *param_idx)
79 {
80 if (glsl_type_is_vector_or_scalar(value->type)) {
81 call->params[(*param_idx)++] = nir_src_for_ssa(value->def);
82 } else {
83 unsigned elems = glsl_get_length(value->type);
84 for (unsigned i = 0; i < elems; i++) {
85 vtn_ssa_value_add_to_call_params(b, value->elems[i],
86 call, param_idx);
87 }
88 }
89 }
90
91 struct vtn_func_arg_info {
92 bool by_value;
93 };
94
95 static void
function_parameter_decoration_cb(struct vtn_builder * b,struct vtn_value * val,int member,const struct vtn_decoration * dec,void * arg_info)96 function_parameter_decoration_cb(struct vtn_builder *b, struct vtn_value *val,
97 int member, const struct vtn_decoration *dec,
98 void *arg_info)
99 {
100 struct vtn_func_arg_info *info = arg_info;
101
102 switch (dec->decoration) {
103 case SpvDecorationFuncParamAttr:
104 for (uint32_t i = 0; i < dec->num_operands; i++) {
105 uint32_t attr = dec->operands[i];
106 switch (attr) {
107 /* ignore for now */
108 case SpvFunctionParameterAttributeNoAlias:
109 case SpvFunctionParameterAttributeSext:
110 case SpvFunctionParameterAttributeZext:
111 case SpvFunctionParameterAttributeSret:
112 break;
113
114 case SpvFunctionParameterAttributeByVal:
115 info->by_value = true;
116 break;
117
118 default:
119 vtn_warn("Function parameter Decoration not handled: %s",
120 spirv_functionparameterattribute_to_string(attr));
121 break;
122 }
123 }
124 break;
125
126 /* ignore for now */
127 case SpvDecorationAliased:
128 case SpvDecorationAliasedPointer:
129 case SpvDecorationAlignment:
130 case SpvDecorationRelaxedPrecision:
131 case SpvDecorationRestrict:
132 case SpvDecorationRestrictPointer:
133 case SpvDecorationVolatile:
134 break;
135
136 default:
137 vtn_warn("Function parameter Decoration not handled: %s",
138 spirv_decoration_to_string(dec->decoration));
139 break;
140 }
141 }
142
143 static void
vtn_ssa_value_load_function_param(struct vtn_builder * b,struct vtn_ssa_value * value,struct vtn_type * type,struct vtn_func_arg_info * info,unsigned * param_idx)144 vtn_ssa_value_load_function_param(struct vtn_builder *b,
145 struct vtn_ssa_value *value,
146 struct vtn_type *type,
147 struct vtn_func_arg_info *info,
148 unsigned *param_idx)
149 {
150 if (glsl_type_is_vector_or_scalar(value->type)) {
151 /* if the parameter is passed by value, we need to create a local copy if it's a pointer */
152 if (info->by_value && type && type->base_type == vtn_base_type_pointer) {
153 struct vtn_type *pointee_type = type->pointed;
154
155 nir_variable *copy =
156 nir_local_variable_create(b->nb.impl, pointee_type->type, NULL);
157
158 nir_variable_mode mode;
159 vtn_storage_class_to_mode(b, type->storage_class, NULL, &mode);
160
161 nir_def *param = nir_load_param(&b->nb, (*param_idx)++);
162 nir_deref_instr *src = nir_build_deref_cast(&b->nb, param, mode, copy->type, 0);
163 nir_deref_instr *dst = nir_build_deref_var(&b->nb, copy);
164
165 nir_copy_deref(&b->nb, dst, src);
166
167 nir_deref_instr *load =
168 nir_build_deref_cast(&b->nb, &dst->def, nir_var_function_temp, type->type, 0);
169 value->def = &load->def;
170 } else {
171 value->def = nir_load_param(&b->nb, (*param_idx)++);
172 }
173 } else {
174 unsigned elems = glsl_get_length(value->type);
175 for (unsigned i = 0; i < elems; i++)
176 vtn_ssa_value_load_function_param(b, value->elems[i], NULL, info, param_idx);
177 }
178 }
179
180 void
vtn_handle_function_call(struct vtn_builder * b,SpvOp opcode,const uint32_t * w,unsigned count)181 vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
182 const uint32_t *w, unsigned count)
183 {
184 struct vtn_function *vtn_callee =
185 vtn_value(b, w[3], vtn_value_type_function)->func;
186
187 vtn_callee->referenced = true;
188
189 nir_call_instr *call = nir_call_instr_create(b->nb.shader,
190 vtn_callee->nir_func);
191
192 unsigned param_idx = 0;
193
194 nir_deref_instr *ret_deref = NULL;
195 struct vtn_type *ret_type = vtn_callee->type->return_type;
196 if (ret_type->base_type != vtn_base_type_void) {
197 nir_variable *ret_tmp =
198 nir_local_variable_create(b->nb.impl,
199 glsl_get_bare_type(ret_type->type),
200 "return_tmp");
201 ret_deref = nir_build_deref_var(&b->nb, ret_tmp);
202 call->params[param_idx++] = nir_src_for_ssa(&ret_deref->def);
203 }
204
205 for (unsigned i = 0; i < vtn_callee->type->length; i++) {
206 vtn_ssa_value_add_to_call_params(b, vtn_ssa_value(b, w[4 + i]),
207 call, ¶m_idx);
208 }
209 assert(param_idx == call->num_params);
210
211 nir_builder_instr_insert(&b->nb, &call->instr);
212
213 if (ret_type->base_type == vtn_base_type_void) {
214 vtn_push_value(b, w[2], vtn_value_type_undef);
215 } else {
216 vtn_push_ssa_value(b, w[2], vtn_local_load(b, ret_deref, 0));
217 }
218 }
219
220 static void
function_decoration_cb(struct vtn_builder * b,struct vtn_value * val,int member,const struct vtn_decoration * dec,void * void_func)221 function_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
222 const struct vtn_decoration *dec, void *void_func)
223 {
224 struct vtn_function *func = void_func;
225
226 switch (dec->decoration) {
227 case SpvDecorationLinkageAttributes: {
228 unsigned name_words;
229 const char *name =
230 vtn_string_literal(b, dec->operands, dec->num_operands, &name_words);
231 vtn_fail_if(name_words >= dec->num_operands,
232 "Malformed LinkageAttributes decoration");
233 (void)name; /* TODO: What is this? */
234 func->linkage = dec->operands[name_words];
235 break;
236 }
237
238 default:
239 break;
240 }
241 }
242
243 /*
244 * Usually, execution modes are per-shader and handled elsewhere. However, with
245 * create_library we will have modes per-nir_function. We can't represent all
246 * SPIR-V execution modes in nir_function, so this is lossy for multi-entrypoint
247 * SPIR-V. However, we do have workgroup_size in nir_function so we gather that
248 * here. If other execution modes are needed in the multi-entrypoint case, both
249 * nir_function and this callback will need to be extended suitably.
250 */
251 static void
function_execution_mode_cb(struct vtn_builder * b,struct vtn_value * func,const struct vtn_decoration * mode,void * data)252 function_execution_mode_cb(struct vtn_builder *b, struct vtn_value *func,
253 const struct vtn_decoration *mode, void *data)
254 {
255 nir_function *nir_func = data;
256
257 if (mode->exec_mode == SpvExecutionModeLocalSize) {
258 vtn_assert(b->shader->info.stage == MESA_SHADER_KERNEL);
259
260 nir_func->workgroup_size[0] = mode->operands[0];
261 nir_func->workgroup_size[1] = mode->operands[1];
262 nir_func->workgroup_size[2] = mode->operands[2];
263 }
264 }
265
266 bool
vtn_cfg_handle_prepass_instruction(struct vtn_builder * b,SpvOp opcode,const uint32_t * w,unsigned count)267 vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
268 const uint32_t *w, unsigned count)
269 {
270 switch (opcode) {
271 case SpvOpFunction: {
272 vtn_assert(b->func == NULL);
273 b->func = vtn_zalloc(b, struct vtn_function);
274
275 list_inithead(&b->func->body);
276 b->func->linkage = SpvLinkageTypeMax;
277 b->func->control = w[3];
278 list_inithead(&b->func->constructs);
279
280 UNUSED const struct glsl_type *result_type = vtn_get_type(b, w[1])->type;
281 struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
282 val->func = b->func;
283
284 vtn_foreach_decoration(b, val, function_decoration_cb, b->func);
285
286 b->func->type = vtn_get_type(b, w[4]);
287 const struct vtn_type *func_type = b->func->type;
288
289 vtn_assert(func_type->return_type->type == result_type);
290
291 nir_function *func =
292 nir_function_create(b->shader, ralloc_strdup(b->shader, val->name));
293
294 /* Execution modes are gathered per-function with create_library (here)
295 * but per shader with !create_library (elsewhere).
296 */
297 if (b->options->create_library)
298 vtn_foreach_execution_mode(b, val, function_execution_mode_cb, func);
299
300 unsigned num_params = 0;
301 for (unsigned i = 0; i < func_type->length; i++)
302 num_params += glsl_type_count_function_params(func_type->params[i]->type);
303
304 /* Add one parameter for the function return value */
305 if (func_type->return_type->base_type != vtn_base_type_void)
306 num_params++;
307
308 func->should_inline = b->func->control & SpvFunctionControlInlineMask;
309 func->dont_inline = b->func->control & SpvFunctionControlDontInlineMask;
310 func->is_exported = b->func->linkage == SpvLinkageTypeExport;
311
312 /* This is a bit subtle: if we are compiling a non-library, we will have
313 * exactly one entrypoint. But in library mode, we can have 0, 1, or even
314 * multiple entrypoints. This is OK.
315 *
316 * So, we set is_entrypoint for libraries here (plumbing OpEntryPoint),
317 * but set is_entrypoint elsewhere for graphics shaders.
318 */
319 if (b->options->create_library) {
320 func->is_entrypoint = val->is_entrypoint;
321 }
322
323 func->num_params = num_params;
324 func->params = rzalloc_array(b->shader, nir_parameter, num_params);
325
326 unsigned idx = 0;
327 if (func_type->return_type->base_type != vtn_base_type_void) {
328 nir_address_format addr_format =
329 vtn_mode_to_address_format(b, vtn_variable_mode_function);
330 /* The return value is a regular pointer */
331 func->params[idx++] = (nir_parameter) {
332 .num_components = nir_address_format_num_components(addr_format),
333 .bit_size = nir_address_format_bit_size(addr_format),
334 };
335 }
336
337 for (unsigned i = 0; i < func_type->length; i++)
338 glsl_type_add_to_function_params(func_type->params[i]->type, func, &idx);
339 assert(idx == num_params);
340
341 b->func->nir_func = func;
342
343 /* Set up a nir_function_impl and the builder so we can load arguments
344 * directly in our OpFunctionParameter handler.
345 */
346 nir_function_impl *impl = nir_function_impl_create(func);
347 b->nb = nir_builder_at(nir_before_impl(impl));
348 b->nb.exact = b->exact;
349
350 b->func_param_idx = 0;
351
352 /* The return value is the first parameter */
353 if (func_type->return_type->base_type != vtn_base_type_void)
354 b->func_param_idx++;
355 break;
356 }
357
358 case SpvOpFunctionEnd:
359 b->func->end = w;
360 if (b->func->start_block == NULL) {
361 vtn_fail_if(b->func->linkage != SpvLinkageTypeImport,
362 "A function declaration (an OpFunction with no basic "
363 "blocks), must have a Linkage Attributes Decoration "
364 "with the Import Linkage Type.");
365
366 /* In this case, the function didn't have any actual blocks. It's
367 * just a prototype so delete the function_impl.
368 */
369 b->func->nir_func->impl = NULL;
370 } else {
371 vtn_fail_if(b->func->linkage == SpvLinkageTypeImport,
372 "A function definition (an OpFunction with basic blocks) "
373 "cannot be decorated with the Import Linkage Type.");
374 }
375 b->func = NULL;
376 break;
377
378 case SpvOpFunctionParameter: {
379 vtn_assert(b->func_param_idx < b->func->nir_func->num_params);
380
381 struct vtn_func_arg_info arg_info = {0};
382 struct vtn_type *type = vtn_get_type(b, w[1]);
383 struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, type->type);
384 struct vtn_value *val = vtn_untyped_value(b, w[2]);
385
386 b->func->nir_func->params[b->func_param_idx].name = val->name;
387
388 vtn_foreach_decoration(b, val, function_parameter_decoration_cb, &arg_info);
389 vtn_ssa_value_load_function_param(b, ssa, type, &arg_info, &b->func_param_idx);
390 vtn_push_ssa_value(b, w[2], ssa);
391 break;
392 }
393
394 case SpvOpLabel: {
395 vtn_assert(b->block == NULL);
396 b->block = vtn_zalloc(b, struct vtn_block);
397 b->block->label = w;
398 vtn_push_value(b, w[1], vtn_value_type_block)->block = b->block;
399
400 b->func->block_count++;
401
402 if (b->func->start_block == NULL) {
403 /* This is the first block encountered for this function. In this
404 * case, we set the start block and add it to the list of
405 * implemented functions that we'll walk later.
406 */
407 b->func->start_block = b->block;
408 list_addtail(&b->func->link, &b->functions);
409 }
410 break;
411 }
412
413 case SpvOpSelectionMerge:
414 case SpvOpLoopMerge:
415 vtn_assert(b->block && b->block->merge == NULL);
416 b->block->merge = w;
417 break;
418
419 case SpvOpBranch:
420 case SpvOpBranchConditional:
421 case SpvOpSwitch:
422 case SpvOpKill:
423 case SpvOpTerminateInvocation:
424 case SpvOpIgnoreIntersectionKHR:
425 case SpvOpTerminateRayKHR:
426 case SpvOpEmitMeshTasksEXT:
427 case SpvOpReturn:
428 case SpvOpReturnValue:
429 case SpvOpUnreachable:
430 if (b->wa_ignore_return_after_emit_mesh_tasks &&
431 opcode == SpvOpReturn && !b->block) {
432 /* At this point block was already reset by
433 * SpvOpEmitMeshTasksEXT. */
434 break;
435 }
436 vtn_assert(b->block && b->block->branch == NULL);
437 b->block->branch = w;
438 b->block = NULL;
439 break;
440
441 default:
442 /* Continue on as per normal */
443 return true;
444 }
445
446 return true;
447 }
448
449 /* returns the default block */
450 void
vtn_parse_switch(struct vtn_builder * b,const uint32_t * branch,struct list_head * case_list)451 vtn_parse_switch(struct vtn_builder *b,
452 const uint32_t *branch,
453 struct list_head *case_list)
454 {
455 const uint32_t *branch_end = branch + (branch[0] >> SpvWordCountShift);
456
457 struct vtn_value *sel_val = vtn_untyped_value(b, branch[1]);
458 vtn_fail_if(!sel_val->type ||
459 sel_val->type->base_type != vtn_base_type_scalar,
460 "Selector of OpSwitch must have a type of OpTypeInt");
461
462 nir_alu_type sel_type =
463 nir_get_nir_type_for_glsl_type(sel_val->type->type);
464 vtn_fail_if(nir_alu_type_get_base_type(sel_type) != nir_type_int &&
465 nir_alu_type_get_base_type(sel_type) != nir_type_uint,
466 "Selector of OpSwitch must have a type of OpTypeInt");
467
468 struct hash_table *block_to_case = _mesa_pointer_hash_table_create(b);
469
470 bool is_default = true;
471 const unsigned bitsize = nir_alu_type_get_type_size(sel_type);
472 for (const uint32_t *w = branch + 2; w < branch_end;) {
473 uint64_t literal = 0;
474 if (!is_default) {
475 if (bitsize <= 32) {
476 literal = *(w++);
477 } else {
478 assert(bitsize == 64);
479 literal = vtn_u64_literal(w);
480 w += 2;
481 }
482 }
483 struct vtn_block *case_block = vtn_block(b, *(w++));
484
485 struct hash_entry *case_entry =
486 _mesa_hash_table_search(block_to_case, case_block);
487
488 struct vtn_case *cse;
489 if (case_entry) {
490 cse = case_entry->data;
491 } else {
492 cse = vtn_zalloc(b, struct vtn_case);
493 cse->block = case_block;
494 cse->block->switch_case = cse;
495 util_dynarray_init(&cse->values, b);
496
497 list_addtail(&cse->link, case_list);
498 _mesa_hash_table_insert(block_to_case, case_block, cse);
499 }
500
501 if (is_default) {
502 cse->is_default = true;
503 } else {
504 util_dynarray_append(&cse->values, uint64_t, literal);
505 }
506
507 is_default = false;
508 }
509
510 _mesa_hash_table_destroy(block_to_case, NULL);
511 }
512
513 void
vtn_build_cfg(struct vtn_builder * b,const uint32_t * words,const uint32_t * end)514 vtn_build_cfg(struct vtn_builder *b, const uint32_t *words, const uint32_t *end)
515 {
516 vtn_foreach_instruction(b, words, end,
517 vtn_cfg_handle_prepass_instruction);
518
519 if (b->shader->info.stage == MESA_SHADER_KERNEL)
520 return;
521
522 vtn_build_structured_cfg(b, words, end);
523 }
524
525 bool
vtn_handle_phis_first_pass(struct vtn_builder * b,SpvOp opcode,const uint32_t * w,unsigned count)526 vtn_handle_phis_first_pass(struct vtn_builder *b, SpvOp opcode,
527 const uint32_t *w, unsigned count)
528 {
529 if (opcode == SpvOpLabel)
530 return true; /* Nothing to do */
531
532 /* If this isn't a phi node, stop. */
533 if (opcode != SpvOpPhi)
534 return false;
535
536 /* For handling phi nodes, we do a poor-man's out-of-ssa on the spot.
537 * For each phi, we create a variable with the appropreate type and
538 * do a load from that variable. Then, in a second pass, we add
539 * stores to that variable to each of the predecessor blocks.
540 *
541 * We could do something more intelligent here. However, in order to
542 * handle loops and things properly, we really need dominance
543 * information. It would end up basically being the into-SSA
544 * algorithm all over again. It's easier if we just let
545 * lower_vars_to_ssa do that for us instead of repeating it here.
546 */
547 struct vtn_type *type = vtn_get_type(b, w[1]);
548 nir_variable *phi_var =
549 nir_local_variable_create(b->nb.impl, type->type, "phi");
550
551 struct vtn_value *phi_val = vtn_untyped_value(b, w[2]);
552 if (vtn_value_is_relaxed_precision(b, phi_val))
553 phi_var->data.precision = GLSL_PRECISION_MEDIUM;
554
555 _mesa_hash_table_insert(b->phi_table, w, phi_var);
556
557 vtn_push_ssa_value(b, w[2],
558 vtn_local_load(b, nir_build_deref_var(&b->nb, phi_var), 0));
559
560 return true;
561 }
562
563 static bool
vtn_handle_phi_second_pass(struct vtn_builder * b,SpvOp opcode,const uint32_t * w,unsigned count)564 vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
565 const uint32_t *w, unsigned count)
566 {
567 if (opcode != SpvOpPhi)
568 return true;
569
570 struct hash_entry *phi_entry = _mesa_hash_table_search(b->phi_table, w);
571
572 /* It's possible that this phi is in an unreachable block in which case it
573 * may never have been emitted and therefore may not be in the hash table.
574 * In this case, there's no var for it and it's safe to just bail.
575 */
576 if (phi_entry == NULL)
577 return true;
578
579 nir_variable *phi_var = phi_entry->data;
580
581 for (unsigned i = 3; i < count; i += 2) {
582 struct vtn_block *pred = vtn_block(b, w[i + 1]);
583
584 /* If block does not have end_nop, that is because it is an unreacheable
585 * block, and hence it is not worth to handle it */
586 if (!pred->end_nop)
587 continue;
588
589 b->nb.cursor = nir_after_instr(&pred->end_nop->instr);
590
591 struct vtn_ssa_value *src = vtn_ssa_value(b, w[i]);
592
593 vtn_local_store(b, src, nir_build_deref_var(&b->nb, phi_var), 0);
594 }
595
596 return true;
597 }
598
599 void
vtn_emit_ret_store(struct vtn_builder * b,const struct vtn_block * block)600 vtn_emit_ret_store(struct vtn_builder *b, const struct vtn_block *block)
601 {
602 if ((*block->branch & SpvOpCodeMask) != SpvOpReturnValue)
603 return;
604
605 vtn_fail_if(b->func->type->return_type->base_type == vtn_base_type_void,
606 "Return with a value from a function returning void");
607 struct vtn_ssa_value *src = vtn_ssa_value(b, block->branch[1]);
608 const struct glsl_type *ret_type =
609 glsl_get_bare_type(b->func->type->return_type->type);
610 nir_deref_instr *ret_deref =
611 nir_build_deref_cast(&b->nb, nir_load_param(&b->nb, 0),
612 nir_var_function_temp, ret_type, 0);
613 vtn_local_store(b, src, ret_deref, 0);
614 }
615
616 static struct nir_block *
vtn_new_unstructured_block(struct vtn_builder * b,struct vtn_function * func)617 vtn_new_unstructured_block(struct vtn_builder *b, struct vtn_function *func)
618 {
619 struct nir_block *n = nir_block_create(b->shader);
620 exec_list_push_tail(&func->nir_func->impl->body, &n->cf_node.node);
621 n->cf_node.parent = &func->nir_func->impl->cf_node;
622 return n;
623 }
624
625 static void
vtn_add_unstructured_block(struct vtn_builder * b,struct vtn_function * func,struct list_head * work_list,struct vtn_block * block)626 vtn_add_unstructured_block(struct vtn_builder *b,
627 struct vtn_function *func,
628 struct list_head *work_list,
629 struct vtn_block *block)
630 {
631 if (!block->block) {
632 block->block = vtn_new_unstructured_block(b, func);
633 list_addtail(&block->link, work_list);
634 }
635 }
636
637 static void
vtn_emit_cf_func_unstructured(struct vtn_builder * b,struct vtn_function * func,vtn_instruction_handler handler)638 vtn_emit_cf_func_unstructured(struct vtn_builder *b, struct vtn_function *func,
639 vtn_instruction_handler handler)
640 {
641 struct list_head work_list;
642 list_inithead(&work_list);
643
644 func->start_block->block = nir_start_block(func->nir_func->impl);
645 list_addtail(&func->start_block->link, &work_list);
646 while (!list_is_empty(&work_list)) {
647 struct vtn_block *block =
648 list_first_entry(&work_list, struct vtn_block, link);
649 list_del(&block->link);
650
651 vtn_assert(block->block);
652
653 const uint32_t *block_start = block->label;
654 const uint32_t *block_end = block->branch;
655
656 b->nb.cursor = nir_after_block(block->block);
657 block_start = vtn_foreach_instruction(b, block_start, block_end,
658 vtn_handle_phis_first_pass);
659 vtn_foreach_instruction(b, block_start, block_end, handler);
660 block->end_nop = nir_nop(&b->nb);
661
662 SpvOp op = *block_end & SpvOpCodeMask;
663 switch (op) {
664 case SpvOpBranch: {
665 struct vtn_block *branch_block = vtn_block(b, block->branch[1]);
666 vtn_add_unstructured_block(b, func, &work_list, branch_block);
667 nir_goto(&b->nb, branch_block->block);
668 break;
669 }
670
671 case SpvOpBranchConditional: {
672 nir_def *cond = vtn_ssa_value(b, block->branch[1])->def;
673 struct vtn_block *then_block = vtn_block(b, block->branch[2]);
674 struct vtn_block *else_block = vtn_block(b, block->branch[3]);
675
676 vtn_add_unstructured_block(b, func, &work_list, then_block);
677 if (then_block == else_block) {
678 nir_goto(&b->nb, then_block->block);
679 } else {
680 vtn_add_unstructured_block(b, func, &work_list, else_block);
681 nir_goto_if(&b->nb, then_block->block, cond, else_block->block);
682 }
683
684 break;
685 }
686
687 case SpvOpSwitch: {
688 struct list_head cases;
689 list_inithead(&cases);
690 vtn_parse_switch(b, block->branch, &cases);
691
692 nir_def *sel = vtn_get_nir_ssa(b, block->branch[1]);
693
694 struct vtn_case *def = NULL;
695 vtn_foreach_case(cse, &cases) {
696 if (cse->is_default) {
697 assert(def == NULL);
698 def = cse;
699 continue;
700 }
701
702 nir_def *cond = nir_imm_false(&b->nb);
703 util_dynarray_foreach(&cse->values, uint64_t, val)
704 cond = nir_ior(&b->nb, cond, nir_ieq_imm(&b->nb, sel, *val));
705
706 /* block for the next check */
707 nir_block *e = vtn_new_unstructured_block(b, func);
708 vtn_add_unstructured_block(b, func, &work_list, cse->block);
709
710 /* add branching */
711 nir_goto_if(&b->nb, cse->block->block, cond, e);
712 b->nb.cursor = nir_after_block(e);
713 }
714
715 vtn_assert(def != NULL);
716 vtn_add_unstructured_block(b, func, &work_list, def->block);
717
718 /* now that all cases are handled, branch into the default block */
719 nir_goto(&b->nb, def->block->block);
720 break;
721 }
722
723 case SpvOpKill: {
724 nir_discard(&b->nb);
725 nir_goto(&b->nb, b->func->nir_func->impl->end_block);
726 break;
727 }
728
729 case SpvOpUnreachable:
730 case SpvOpReturn:
731 case SpvOpReturnValue: {
732 vtn_emit_ret_store(b, block);
733 nir_goto(&b->nb, b->func->nir_func->impl->end_block);
734 break;
735 }
736
737 default:
738 vtn_fail("Unhandled opcode %s", spirv_op_to_string(op));
739 }
740 }
741 }
742
743 void
vtn_function_emit(struct vtn_builder * b,struct vtn_function * func,vtn_instruction_handler instruction_handler)744 vtn_function_emit(struct vtn_builder *b, struct vtn_function *func,
745 vtn_instruction_handler instruction_handler)
746 {
747 static int force_unstructured = -1;
748 if (force_unstructured < 0) {
749 force_unstructured =
750 debug_get_bool_option("MESA_SPIRV_FORCE_UNSTRUCTURED", false);
751 }
752
753 nir_function_impl *impl = func->nir_func->impl;
754 b->nb = nir_builder_at(nir_after_impl(impl));
755 b->func = func;
756 b->nb.exact = b->exact;
757 b->phi_table = _mesa_pointer_hash_table_create(b);
758
759 if (b->shader->info.stage == MESA_SHADER_KERNEL || force_unstructured) {
760 impl->structured = false;
761 vtn_emit_cf_func_unstructured(b, func, instruction_handler);
762 } else {
763 vtn_emit_cf_func_structured(b, func, instruction_handler);
764 }
765
766 vtn_foreach_instruction(b, func->start_block->label, func->end,
767 vtn_handle_phi_second_pass);
768
769 if (func->nir_func->impl->structured)
770 nir_copy_prop_impl(impl);
771 nir_rematerialize_derefs_in_use_blocks_impl(impl);
772
773 /*
774 * There are some cases where we need to repair SSA to insert
775 * the needed phi nodes:
776 *
777 * - Early termination instructions `OpKill` and `OpTerminateInvocation`,
778 * in NIR. They're represented by regular intrinsics with no control-flow
779 * semantics. This means that the SSA form from the SPIR-V may not
780 * 100% match NIR.
781 *
782 * - Switches with only default case may also define SSA which may
783 * subsequently be used out of the switch.
784 */
785 if (func->nir_func->impl->structured)
786 nir_repair_ssa_impl(impl);
787
788 func->emitted = true;
789 }
790