• 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          .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, &param_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