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