• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param_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