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