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