nir/search: handle explicitly sized sources in match_value
[mesa.git] / src / glsl / nir / nir_print.c
1 /*
2 * Copyright © 2014 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 * Authors:
24 * Connor Abbott (cwabbott0@gmail.com)
25 *
26 */
27
28 #include "nir.h"
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 static void
33 print_tabs(unsigned num_tabs, FILE *fp)
34 {
35 for (unsigned i = 0; i < num_tabs; i++)
36 fprintf(fp, "\t");
37 }
38
39 typedef struct {
40 /** map from nir_variable -> printable name */
41 struct hash_table *ht;
42
43 /** set of names used so far for nir_variables */
44 struct set *syms;
45
46 /* an index used to make new non-conflicting names */
47 unsigned index;
48 } print_var_state;
49
50 static void
51 print_register(nir_register *reg, FILE *fp)
52 {
53 if (reg->name != NULL)
54 fprintf(fp, "/* %s */ ", reg->name);
55 if (reg->is_global)
56 fprintf(fp, "gr%u", reg->index);
57 else
58 fprintf(fp, "r%u", reg->index);
59 }
60
61 static const char *sizes[] = { "error", "vec1", "vec2", "vec3", "vec4" };
62
63 static void
64 print_register_decl(nir_register *reg, FILE *fp)
65 {
66 fprintf(fp, "decl_reg %s ", sizes[reg->num_components]);
67 if (reg->is_packed)
68 fprintf(fp, "(packed) ");
69 print_register(reg, fp);
70 if (reg->num_array_elems != 0)
71 fprintf(fp, "[%u]", reg->num_array_elems);
72 fprintf(fp, "\n");
73 }
74
75 static void
76 print_ssa_def(nir_ssa_def *def, FILE *fp)
77 {
78 if (def->name != NULL)
79 fprintf(fp, "/* %s */ ", def->name);
80 fprintf(fp, "%s ssa_%u", sizes[def->num_components], def->index);
81 }
82
83 static void
84 print_ssa_use(nir_ssa_def *def, FILE *fp)
85 {
86 if (def->name != NULL)
87 fprintf(fp, "/* %s */ ", def->name);
88 fprintf(fp, "ssa_%u", def->index);
89 }
90
91 static void print_src(nir_src *src, FILE *fp);
92
93 static void
94 print_reg_src(nir_reg_src *src, FILE *fp)
95 {
96 print_register(src->reg, fp);
97 if (src->reg->num_array_elems != 0) {
98 fprintf(fp, "[%u", src->base_offset);
99 if (src->indirect != NULL) {
100 fprintf(fp, " + ");
101 print_src(src->indirect, fp);
102 }
103 fprintf(fp, "]");
104 }
105 }
106
107 static void
108 print_reg_dest(nir_reg_dest *dest, FILE *fp)
109 {
110 print_register(dest->reg, fp);
111 if (dest->reg->num_array_elems != 0) {
112 fprintf(fp, "[%u", dest->base_offset);
113 if (dest->indirect != NULL) {
114 fprintf(fp, " + ");
115 print_src(dest->indirect, fp);
116 }
117 fprintf(fp, "]");
118 }
119 }
120
121 static void
122 print_src(nir_src *src, FILE *fp)
123 {
124 if (src->is_ssa)
125 print_ssa_use(src->ssa, fp);
126 else
127 print_reg_src(&src->reg, fp);
128 }
129
130 static void
131 print_dest(nir_dest *dest, FILE *fp)
132 {
133 if (dest->is_ssa)
134 print_ssa_def(&dest->ssa, fp);
135 else
136 print_reg_dest(&dest->reg, fp);
137 }
138
139 static void
140 print_alu_src(nir_alu_instr *instr, unsigned src, FILE *fp)
141 {
142 if (instr->src[src].negate)
143 fprintf(fp, "-");
144 if (instr->src[src].abs)
145 fprintf(fp, "abs(");
146
147 print_src(&instr->src[src].src, fp);
148
149 bool print_swizzle = false;
150 for (unsigned i = 0; i < 4; i++) {
151 if (!nir_alu_instr_channel_used(instr, src, i))
152 continue;
153
154 if (instr->src[src].swizzle[i] != i) {
155 print_swizzle = true;
156 break;
157 }
158 }
159
160 if (print_swizzle) {
161 fprintf(fp, ".");
162 for (unsigned i = 0; i < 4; i++) {
163 if (!nir_alu_instr_channel_used(instr, src, i))
164 continue;
165
166 fprintf(fp, "%c", "xyzw"[instr->src[src].swizzle[i]]);
167 }
168 }
169
170 if (instr->src[src].abs)
171 fprintf(fp, ")");
172 }
173
174 static void
175 print_alu_dest(nir_alu_dest *dest, FILE *fp)
176 {
177 /* we're going to print the saturate modifier later, after the opcode */
178
179 print_dest(&dest->dest, fp);
180
181 if (!dest->dest.is_ssa &&
182 dest->write_mask != (1 << dest->dest.reg.reg->num_components) - 1) {
183 fprintf(fp, ".");
184 for (unsigned i = 0; i < 4; i++)
185 if ((dest->write_mask >> i) & 1)
186 fprintf(fp, "%c", "xyzw"[i]);
187 }
188 }
189
190 static void
191 print_alu_instr(nir_alu_instr *instr, FILE *fp)
192 {
193 print_alu_dest(&instr->dest, fp);
194
195 fprintf(fp, " = %s", nir_op_infos[instr->op].name);
196 if (instr->dest.saturate)
197 fprintf(fp, ".sat");
198 fprintf(fp, " ");
199
200 for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
201 if (i != 0)
202 fprintf(fp, ", ");
203
204 print_alu_src(instr, i, fp);
205 }
206 }
207
208 static void
209 print_var_decl(nir_variable *var, print_var_state *state, FILE *fp)
210 {
211 fprintf(fp, "decl_var ");
212
213 const char *const cent = (var->data.centroid) ? "centroid " : "";
214 const char *const samp = (var->data.sample) ? "sample " : "";
215 const char *const inv = (var->data.invariant) ? "invariant " : "";
216 const char *const mode[] = { "shader_in ", "shader_out ", "", "",
217 "uniform ", "system " };
218 const char *const interp[] = { "", "smooth", "flat", "noperspective" };
219
220 fprintf(fp, "%s%s%s%s%s ",
221 cent, samp, inv, mode[var->data.mode], interp[var->data.interpolation]);
222
223 glsl_print_type(var->type, fp);
224
225 struct set_entry *entry = NULL;
226 if (state)
227 entry = _mesa_set_search(state->syms, var->name);
228
229 char *name;
230
231 if (entry != NULL) {
232 /* we have a collision with another name, append an @ + a unique index */
233 name = ralloc_asprintf(state->syms, "%s@%u", var->name, state->index++);
234 } else {
235 name = var->name;
236 }
237
238 fprintf(fp, " %s", name);
239
240 if (var->data.mode == nir_var_shader_in ||
241 var->data.mode == nir_var_shader_out ||
242 var->data.mode == nir_var_uniform) {
243 fprintf(fp, " (%u, %u)", var->data.location, var->data.driver_location);
244 }
245
246 fprintf(fp, "\n");
247
248 if (state) {
249 _mesa_set_add(state->syms, name);
250 _mesa_hash_table_insert(state->ht, var, name);
251 }
252 }
253
254 static void
255 print_var(nir_variable *var, print_var_state *state, FILE *fp)
256 {
257 const char *name;
258 if (state) {
259 struct hash_entry *entry = _mesa_hash_table_search(state->ht, var);
260
261 assert(entry != NULL);
262 name = entry->data;
263 } else {
264 name = var->name;
265 }
266
267 fprintf(fp, "%s", name);
268 }
269
270 static void
271 print_deref_var(nir_deref_var *deref, print_var_state *state, FILE *fp)
272 {
273 print_var(deref->var, state, fp);
274 }
275
276 static void
277 print_deref_array(nir_deref_array *deref, print_var_state *state, FILE *fp)
278 {
279 fprintf(fp, "[");
280 switch (deref->deref_array_type) {
281 case nir_deref_array_type_direct:
282 fprintf(fp, "%u", deref->base_offset);
283 break;
284 case nir_deref_array_type_indirect:
285 if (deref->base_offset != 0)
286 fprintf(fp, "%u + ", deref->base_offset);
287 print_src(&deref->indirect, fp);
288 break;
289 case nir_deref_array_type_wildcard:
290 fprintf(fp, "*");
291 break;
292 }
293 fprintf(fp, "]");
294 }
295
296 static void
297 print_deref_struct(nir_deref_struct *deref, const struct glsl_type *parent_type,
298 print_var_state *state, FILE *fp)
299 {
300 fprintf(fp, ".%s", glsl_get_struct_elem_name(parent_type, deref->index));
301 }
302
303 static void
304 print_deref(nir_deref_var *deref, print_var_state *state, FILE *fp)
305 {
306 nir_deref *tail = &deref->deref;
307 nir_deref *pretail = NULL;
308 while (tail != NULL) {
309 switch (tail->deref_type) {
310 case nir_deref_type_var:
311 assert(pretail == NULL);
312 assert(tail == &deref->deref);
313 print_deref_var(deref, state, fp);
314 break;
315
316 case nir_deref_type_array:
317 assert(pretail != NULL);
318 print_deref_array(nir_deref_as_array(tail), state, fp);
319 break;
320
321 case nir_deref_type_struct:
322 assert(pretail != NULL);
323 print_deref_struct(nir_deref_as_struct(tail),
324 pretail->type, state, fp);
325 break;
326
327 default:
328 unreachable("Invalid deref type");
329 }
330
331 pretail = tail;
332 tail = pretail->child;
333 }
334 }
335
336 static void
337 print_intrinsic_instr(nir_intrinsic_instr *instr, print_var_state *state,
338 FILE *fp)
339 {
340 unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs;
341
342 if (nir_intrinsic_infos[instr->intrinsic].has_dest) {
343 print_dest(&instr->dest, fp);
344 fprintf(fp, " = ");
345 }
346
347 fprintf(fp, "intrinsic %s (", nir_intrinsic_infos[instr->intrinsic].name);
348
349 for (unsigned i = 0; i < num_srcs; i++) {
350 if (i != 0)
351 fprintf(fp, ", ");
352
353 print_src(&instr->src[i], fp);
354 }
355
356 fprintf(fp, ") (");
357
358 unsigned num_vars = nir_intrinsic_infos[instr->intrinsic].num_variables;
359
360 for (unsigned i = 0; i < num_vars; i++) {
361 if (i != 0)
362 fprintf(fp, ", ");
363
364 print_deref(instr->variables[i], state, fp);
365 }
366
367 fprintf(fp, ") (");
368
369 unsigned num_indices = nir_intrinsic_infos[instr->intrinsic].num_indices;
370
371 for (unsigned i = 0; i < num_indices; i++) {
372 if (i != 0)
373 fprintf(fp, ", ");
374
375 fprintf(fp, "%u", instr->const_index[i]);
376 }
377
378 fprintf(fp, ")");
379 }
380
381 static void
382 print_tex_instr(nir_tex_instr *instr, print_var_state *state, FILE *fp)
383 {
384 print_dest(&instr->dest, fp);
385
386 fprintf(fp, " = ");
387
388 switch (instr->op) {
389 case nir_texop_tex:
390 fprintf(fp, "tex ");
391 break;
392 case nir_texop_txb:
393 fprintf(fp, "txb ");
394 break;
395 case nir_texop_txl:
396 fprintf(fp, "txl ");
397 break;
398 case nir_texop_txd:
399 fprintf(fp, "txd ");
400 break;
401 case nir_texop_txf:
402 fprintf(fp, "txf ");
403 break;
404 case nir_texop_txf_ms:
405 fprintf(fp, "txf_ms ");
406 break;
407 case nir_texop_txs:
408 fprintf(fp, "txs ");
409 break;
410 case nir_texop_lod:
411 fprintf(fp, "lod ");
412 break;
413 case nir_texop_tg4:
414 fprintf(fp, "tg4 ");
415 break;
416 case nir_texop_query_levels:
417 fprintf(fp, "query_levels ");
418 break;
419
420 default:
421 unreachable("Invalid texture operation");
422 break;
423 }
424
425 for (unsigned i = 0; i < instr->num_srcs; i++) {
426 print_src(&instr->src[i].src, fp);
427
428 fprintf(fp, " ");
429
430 switch(instr->src[i].src_type) {
431 case nir_tex_src_coord:
432 fprintf(fp, "(coord)");
433 break;
434 case nir_tex_src_projector:
435 fprintf(fp, "(projector)");
436 break;
437 case nir_tex_src_comparitor:
438 fprintf(fp, "(comparitor)");
439 break;
440 case nir_tex_src_offset:
441 fprintf(fp, "(offset)");
442 break;
443 case nir_tex_src_bias:
444 fprintf(fp, "(bias)");
445 break;
446 case nir_tex_src_lod:
447 fprintf(fp, "(lod)");
448 break;
449 case nir_tex_src_ms_index:
450 fprintf(fp, "(ms_index)");
451 break;
452 case nir_tex_src_ddx:
453 fprintf(fp, "(ddx)");
454 break;
455 case nir_tex_src_ddy:
456 fprintf(fp, "(ddy)");
457 break;
458 case nir_tex_src_sampler_offset:
459 fprintf(fp, "(sampler_offset)");
460 break;
461
462 default:
463 unreachable("Invalid texture source type");
464 break;
465 }
466
467 fprintf(fp, ", ");
468 }
469
470 bool has_nonzero_offset = false;
471 for (unsigned i = 0; i < 4; i++) {
472 if (instr->const_offset[i] != 0) {
473 has_nonzero_offset = true;
474 break;
475 }
476 }
477
478 if (has_nonzero_offset) {
479 fprintf(fp, "[%i %i %i %i] (offset), ",
480 instr->const_offset[0], instr->const_offset[1],
481 instr->const_offset[2], instr->const_offset[3]);
482 }
483
484 if (instr->op == nir_texop_tg4) {
485 fprintf(fp, "%u (gather_component), ", instr->component);
486 }
487
488 if (instr->sampler) {
489 print_deref(instr->sampler, state, fp);
490 } else {
491 fprintf(fp, "%u", instr->sampler_index);
492 }
493
494 fprintf(fp, " (sampler)");
495 }
496
497 static void
498 print_call_instr(nir_call_instr *instr, print_var_state *state, FILE *fp)
499 {
500 fprintf(fp, "call %s ", instr->callee->function->name);
501
502 for (unsigned i = 0; i < instr->num_params; i++) {
503 if (i != 0)
504 fprintf(fp, ", ");
505
506 print_deref(instr->params[i], state, fp);
507 }
508
509 if (instr->return_deref != NULL) {
510 if (instr->num_params != 0)
511 fprintf(fp, ", ");
512 fprintf(fp, "returning ");
513 print_deref(instr->return_deref, state, fp);
514 }
515 }
516
517 static void
518 print_load_const_instr(nir_load_const_instr *instr, unsigned tabs, FILE *fp)
519 {
520 print_ssa_def(&instr->def, fp);
521
522 fprintf(fp, " = load_const (");
523
524 for (unsigned i = 0; i < instr->def.num_components; i++) {
525 if (i != 0)
526 fprintf(fp, ", ");
527
528 /*
529 * we don't really know the type of the constant (if it will be used as a
530 * float or an int), so just print the raw constant in hex for fidelity
531 * and then print the float in a comment for readability.
532 */
533
534 fprintf(fp, "0x%08x /* %f */", instr->value.u[i], instr->value.f[i]);
535 }
536
537 fprintf(fp, ")");
538 }
539
540 static void
541 print_jump_instr(nir_jump_instr *instr, FILE *fp)
542 {
543 switch (instr->type) {
544 case nir_jump_break:
545 fprintf(fp, "break");
546 break;
547
548 case nir_jump_continue:
549 fprintf(fp, "continue");
550 break;
551
552 case nir_jump_return:
553 fprintf(fp, "return");
554 break;
555 }
556 }
557
558 static void
559 print_ssa_undef_instr(nir_ssa_undef_instr* instr, FILE *fp)
560 {
561 print_ssa_def(&instr->def, fp);
562 fprintf(fp, " = undefined");
563 }
564
565 static void
566 print_phi_instr(nir_phi_instr *instr, FILE *fp)
567 {
568 print_dest(&instr->dest, fp);
569 fprintf(fp, " = phi ");
570 nir_foreach_phi_src(instr, src) {
571 if (&src->node != exec_list_get_head(&instr->srcs))
572 fprintf(fp, ", ");
573
574 fprintf(fp, "block_%u: ", src->pred->index);
575 print_src(&src->src, fp);
576 }
577 }
578
579 static void
580 print_parallel_copy_instr(nir_parallel_copy_instr *instr, FILE *fp)
581 {
582 nir_foreach_parallel_copy_entry(instr, entry) {
583 if (&entry->node != exec_list_get_head(&instr->entries))
584 fprintf(fp, "; ");
585
586 print_dest(&entry->dest, fp);
587 fprintf(fp, " = ");
588 print_src(&entry->src, fp);
589 }
590 }
591
592 static void
593 print_instr(const nir_instr *instr, print_var_state *state, unsigned tabs, FILE *fp)
594 {
595 print_tabs(tabs, fp);
596
597 switch (instr->type) {
598 case nir_instr_type_alu:
599 print_alu_instr(nir_instr_as_alu(instr), fp);
600 break;
601
602 case nir_instr_type_call:
603 print_call_instr(nir_instr_as_call(instr), state, fp);
604 break;
605
606 case nir_instr_type_intrinsic:
607 print_intrinsic_instr(nir_instr_as_intrinsic(instr), state, fp);
608 break;
609
610 case nir_instr_type_tex:
611 print_tex_instr(nir_instr_as_tex(instr), state, fp);
612 break;
613
614 case nir_instr_type_load_const:
615 print_load_const_instr(nir_instr_as_load_const(instr), tabs, fp);
616 break;
617
618 case nir_instr_type_jump:
619 print_jump_instr(nir_instr_as_jump(instr), fp);
620 break;
621
622 case nir_instr_type_ssa_undef:
623 print_ssa_undef_instr(nir_instr_as_ssa_undef(instr), fp);
624 break;
625
626 case nir_instr_type_phi:
627 print_phi_instr(nir_instr_as_phi(instr), fp);
628 break;
629
630 case nir_instr_type_parallel_copy:
631 print_parallel_copy_instr(nir_instr_as_parallel_copy(instr), fp);
632 break;
633
634 default:
635 unreachable("Invalid instruction type");
636 break;
637 }
638 }
639
640 static int
641 compare_block_index(const void *p1, const void *p2)
642 {
643 const nir_block *block1 = *((const nir_block **) p1);
644 const nir_block *block2 = *((const nir_block **) p2);
645
646 return (int) block1->index - (int) block2->index;
647 }
648
649 static void print_cf_node(nir_cf_node *node, print_var_state *state,
650 unsigned tabs, FILE *fp);
651
652 static void
653 print_block(nir_block *block, print_var_state *state, unsigned tabs, FILE *fp)
654 {
655 print_tabs(tabs, fp);
656 fprintf(fp, "block block_%u:\n", block->index);
657
658 /* sort the predecessors by index so we consistently print the same thing */
659
660 nir_block **preds =
661 malloc(block->predecessors->entries * sizeof(nir_block *));
662
663 struct set_entry *entry;
664 unsigned i = 0;
665 set_foreach(block->predecessors, entry) {
666 preds[i++] = (nir_block *) entry->key;
667 }
668
669 qsort(preds, block->predecessors->entries, sizeof(nir_block *),
670 compare_block_index);
671
672 print_tabs(tabs, fp);
673 fprintf(fp, "/* preds: ");
674 for (unsigned i = 0; i < block->predecessors->entries; i++) {
675 fprintf(fp, "block_%u ", preds[i]->index);
676 }
677 fprintf(fp, "*/\n");
678
679 free(preds);
680
681 nir_foreach_instr(block, instr) {
682 print_instr(instr, state, tabs, fp);
683 fprintf(fp, "\n");
684 }
685
686 print_tabs(tabs, fp);
687 fprintf(fp, "/* succs: ");
688 for (unsigned i = 0; i < 2; i++)
689 if (block->successors[i]) {
690 fprintf(fp, "block_%u ", block->successors[i]->index);
691 }
692 fprintf(fp, "*/\n");
693 }
694
695 static void
696 print_if(nir_if *if_stmt, print_var_state *state, unsigned tabs, FILE *fp)
697 {
698 print_tabs(tabs, fp);
699 fprintf(fp, "if ");
700 print_src(&if_stmt->condition, fp);
701 fprintf(fp, " {\n");
702 foreach_list_typed(nir_cf_node, node, node, &if_stmt->then_list) {
703 print_cf_node(node, state, tabs + 1, fp);
704 }
705 print_tabs(tabs, fp);
706 fprintf(fp, "} else {\n");
707 foreach_list_typed(nir_cf_node, node, node, &if_stmt->else_list) {
708 print_cf_node(node, state, tabs + 1, fp);
709 }
710 print_tabs(tabs, fp);
711 fprintf(fp, "}\n");
712 }
713
714 static void
715 print_loop(nir_loop *loop, print_var_state *state, unsigned tabs, FILE *fp)
716 {
717 print_tabs(tabs, fp);
718 fprintf(fp, "loop {\n");
719 foreach_list_typed(nir_cf_node, node, node, &loop->body) {
720 print_cf_node(node, state, tabs + 1, fp);
721 }
722 print_tabs(tabs, fp);
723 fprintf(fp, "}\n");
724 }
725
726 static void
727 print_cf_node(nir_cf_node *node, print_var_state *state, unsigned int tabs,
728 FILE *fp)
729 {
730 switch (node->type) {
731 case nir_cf_node_block:
732 print_block(nir_cf_node_as_block(node), state, tabs, fp);
733 break;
734
735 case nir_cf_node_if:
736 print_if(nir_cf_node_as_if(node), state, tabs, fp);
737 break;
738
739 case nir_cf_node_loop:
740 print_loop(nir_cf_node_as_loop(node), state, tabs, fp);
741 break;
742
743 default:
744 unreachable("Invalid CFG node type");
745 }
746 }
747
748 static void
749 print_function_impl(nir_function_impl *impl, print_var_state *state, FILE *fp)
750 {
751 fprintf(fp, "\nimpl %s ", impl->overload->function->name);
752
753 for (unsigned i = 0; i < impl->num_params; i++) {
754 if (i != 0)
755 fprintf(fp, ", ");
756
757 print_var(impl->params[i], state, fp);
758 }
759
760 if (impl->return_var != NULL) {
761 if (impl->num_params != 0)
762 fprintf(fp, ", ");
763 fprintf(fp, "returning ");
764 print_var(impl->return_var, state, fp);
765 }
766
767 fprintf(fp, "{\n");
768
769 foreach_list_typed(nir_variable, var, node, &impl->locals) {
770 fprintf(fp, "\t");
771 print_var_decl(var, state, fp);
772 }
773
774 foreach_list_typed(nir_register, reg, node, &impl->registers) {
775 fprintf(fp, "\t");
776 print_register_decl(reg, fp);
777 }
778
779 nir_index_blocks(impl);
780
781 foreach_list_typed(nir_cf_node, node, node, &impl->body) {
782 print_cf_node(node, state, 1, fp);
783 }
784
785 fprintf(fp, "\tblock block_%u:\n}\n\n", impl->end_block->index);
786 }
787
788 static void
789 print_function_overload(nir_function_overload *overload,
790 print_var_state *state, FILE *fp)
791 {
792 fprintf(fp, "decl_overload %s ", overload->function->name);
793
794 for (unsigned i = 0; i < overload->num_params; i++) {
795 if (i != 0)
796 fprintf(fp, ", ");
797
798 switch (overload->params[i].param_type) {
799 case nir_parameter_in:
800 fprintf(fp, "in ");
801 break;
802 case nir_parameter_out:
803 fprintf(fp, "out ");
804 break;
805 case nir_parameter_inout:
806 fprintf(fp, "inout ");
807 break;
808 default:
809 unreachable("Invalid parameter type");
810 }
811
812 glsl_print_type(overload->params[i].type, fp);
813 }
814
815 if (overload->return_type != NULL) {
816 if (overload->num_params != 0)
817 fprintf(fp, ", ");
818 fprintf(fp, "returning ");
819 glsl_print_type(overload->return_type, fp);
820 }
821
822 fprintf(fp, "\n");
823
824 if (overload->impl != NULL) {
825 print_function_impl(overload->impl, state, fp);
826 return;
827 }
828 }
829
830 static void
831 print_function(nir_function *func, print_var_state *state, FILE *fp)
832 {
833 foreach_list_typed(nir_function_overload, overload, node, &func->overload_list) {
834 print_function_overload(overload, state, fp);
835 }
836 }
837
838 static void
839 init_print_state(print_var_state *state)
840 {
841 state->ht = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
842 _mesa_key_pointer_equal);
843 state->syms = _mesa_set_create(NULL, _mesa_key_hash_string,
844 _mesa_key_string_equal);
845 state->index = 0;
846 }
847
848 static void
849 destroy_print_state(print_var_state *state)
850 {
851 _mesa_hash_table_destroy(state->ht, NULL);
852 _mesa_set_destroy(state->syms, NULL);
853 }
854
855 void
856 nir_print_shader(nir_shader *shader, FILE *fp)
857 {
858 print_var_state state;
859 init_print_state(&state);
860
861 foreach_list_typed(nir_variable, var, node, &shader->uniforms) {
862 print_var_decl(var, &state, fp);
863 }
864
865 foreach_list_typed(nir_variable, var, node, &shader->inputs) {
866 print_var_decl(var, &state, fp);
867 }
868
869 foreach_list_typed(nir_variable, var, node, &shader->outputs) {
870 print_var_decl(var, &state, fp);
871 }
872
873 foreach_list_typed(nir_variable, var, node, &shader->globals) {
874 print_var_decl(var, &state, fp);
875 }
876
877 foreach_list_typed(nir_variable, var, node, &shader->system_values) {
878 print_var_decl(var, &state, fp);
879 }
880
881 foreach_list_typed(nir_register, reg, node, &shader->registers) {
882 print_register_decl(reg, fp);
883 }
884
885 foreach_list_typed(nir_function, func, node, &shader->functions) {
886 print_function(func, &state, fp);
887 }
888
889 destroy_print_state(&state);
890 }
891
892 void
893 nir_print_instr(const nir_instr *instr, FILE *fp)
894 {
895 print_instr(instr, NULL, 0, fp);
896 }