glsl: define __STDC_FORMAT_MACROS to get PRIx64 macro
[mesa.git] / src / compiler / glsl / ir_builder_print_visitor.cpp
1 /*
2 * Copyright © 2016 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
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #define __STDC_FORMAT_MACROS 1
25 #include <inttypes.h> /* for PRIx64 macro */
26 #include "ir.h"
27 #include "ir_hierarchical_visitor.h"
28 #include "ir_builder_print_visitor.h"
29 #include "compiler/glsl_types.h"
30 #include "glsl_parser_extras.h"
31 #include "main/macros.h"
32 #include "util/hash_table.h"
33
34 class ir_builder_print_visitor : public ir_hierarchical_visitor {
35 public:
36 ir_builder_print_visitor(FILE *f);
37 virtual ~ir_builder_print_visitor();
38
39 void indent(void);
40
41 virtual ir_visitor_status visit(class ir_variable *);
42 virtual ir_visitor_status visit(class ir_dereference_variable *);
43 virtual ir_visitor_status visit(class ir_constant *);
44 virtual ir_visitor_status visit(class ir_loop_jump *);
45
46 virtual ir_visitor_status visit_enter(class ir_if *);
47
48 virtual ir_visitor_status visit_enter(class ir_loop *);
49 virtual ir_visitor_status visit_leave(class ir_loop *);
50
51 virtual ir_visitor_status visit_enter(class ir_function_signature *);
52 virtual ir_visitor_status visit_leave(class ir_function_signature *);
53
54 virtual ir_visitor_status visit_enter(class ir_expression *);
55
56 virtual ir_visitor_status visit_enter(class ir_assignment *);
57 virtual ir_visitor_status visit_leave(class ir_assignment *);
58
59 virtual ir_visitor_status visit_leave(class ir_call *);
60 virtual ir_visitor_status visit_leave(class ir_swizzle *);
61 virtual ir_visitor_status visit_leave(class ir_return *);
62
63 private:
64 void print_with_indent(const char *fmt, ...);
65 void print_without_indent(const char *fmt, ...);
66
67 void print_without_declaration(const ir_rvalue *ir);
68 void print_without_declaration(const ir_constant *ir);
69 void print_without_declaration(const ir_dereference_variable *ir);
70 void print_without_declaration(const ir_swizzle *ir);
71 void print_without_declaration(const ir_expression *ir);
72
73 unsigned next_ir_index;
74
75 /**
76 * Mapping from ir_instruction * -> index used in the generated C code
77 * variable name.
78 */
79 hash_table *index_map;
80
81 FILE *f;
82
83 int indentation;
84 };
85
86 /* An operand is "simple" if it can be compactly printed on one line.
87 */
88 static bool
89 is_simple_operand(const ir_rvalue *ir, unsigned depth = 1)
90 {
91 if (depth == 0)
92 return false;
93
94 switch (ir->ir_type) {
95 case ir_type_dereference_variable:
96 return true;
97
98 case ir_type_constant: {
99 if (ir->type == glsl_type::uint_type ||
100 ir->type == glsl_type::int_type ||
101 ir->type == glsl_type::float_type ||
102 ir->type == glsl_type::bool_type)
103 return true;
104
105 const ir_constant *const c = (ir_constant *) ir;
106 ir_constant_data all_zero;
107 memset(&all_zero, 0, sizeof(all_zero));
108
109 return memcmp(&c->value, &all_zero, sizeof(all_zero)) == 0;
110 }
111
112 case ir_type_swizzle: {
113 const ir_swizzle *swiz = (ir_swizzle *) ir;
114 return swiz->mask.num_components == 1 &&
115 is_simple_operand(swiz->val, depth);
116 }
117
118 case ir_type_expression: {
119 const ir_expression *expr = (ir_expression *) ir;
120
121 for (unsigned i = 0; i < expr->get_num_operands(); i++) {
122 if (!is_simple_operand(expr->operands[i], depth - 1))
123 return false;
124 }
125
126 return true;
127 }
128
129 default:
130 return false;
131 }
132 }
133
134 void
135 _mesa_print_builder_for_ir(FILE *f, exec_list *instructions)
136 {
137 ir_builder_print_visitor v(f);
138 v.run(instructions);
139 }
140
141 ir_builder_print_visitor::ir_builder_print_visitor(FILE *f)
142 : next_ir_index(1), f(f), indentation(0)
143 {
144 index_map =
145 _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
146 }
147
148 ir_builder_print_visitor::~ir_builder_print_visitor()
149 {
150 _mesa_hash_table_destroy(index_map, NULL);
151 }
152
153 void ir_builder_print_visitor::indent(void)
154 {
155 for (int i = 0; i < indentation; i++)
156 fprintf(f, " ");
157 }
158
159 void
160 ir_builder_print_visitor::print_with_indent(const char *fmt, ...)
161 {
162 va_list ap;
163
164 indent();
165
166 va_start(ap, fmt);
167 vfprintf(f, fmt, ap);
168 va_end(ap);
169 }
170
171 void
172 ir_builder_print_visitor::print_without_indent(const char *fmt, ...)
173 {
174 va_list ap;
175
176 va_start(ap, fmt);
177 vfprintf(f, fmt, ap);
178 va_end(ap);
179 }
180
181 void
182 ir_builder_print_visitor::print_without_declaration(const ir_rvalue *ir)
183 {
184 switch (ir->ir_type) {
185 case ir_type_dereference_variable:
186 print_without_declaration((ir_dereference_variable *) ir);
187 break;
188 case ir_type_constant:
189 print_without_declaration((ir_constant *) ir);
190 break;
191 case ir_type_swizzle:
192 print_without_declaration((ir_swizzle *) ir);
193 break;
194 case ir_type_expression:
195 print_without_declaration((ir_expression *) ir);
196 break;
197 default:
198 unreachable("Invalid IR type.");
199 }
200 }
201
202 ir_visitor_status
203 ir_builder_print_visitor::visit(ir_variable *ir)
204 {
205 const unsigned my_index = next_ir_index++;
206
207 _mesa_hash_table_insert(index_map, ir, (void *)(uintptr_t) my_index);
208
209 const char *mode_str;
210 switch (ir->data.mode) {
211 case ir_var_auto: mode_str = "ir_var_auto"; break;
212 case ir_var_uniform: mode_str = "ir_var_uniform"; break;
213 case ir_var_shader_storage: mode_str = "ir_var_shader_storage"; break;
214 case ir_var_shader_shared: mode_str = "ir_var_shader_shared"; break;
215 case ir_var_shader_in: mode_str = "ir_var_shader_in"; break;
216 case ir_var_shader_out: mode_str = "ir_var_shader_out"; break;
217 case ir_var_function_in: mode_str = "ir_var_function_in"; break;
218 case ir_var_function_out: mode_str = "ir_var_function_out"; break;
219 case ir_var_function_inout: mode_str = "ir_var_function_inout"; break;
220 case ir_var_const_in: mode_str = "ir_var_const_in"; break;
221 case ir_var_system_value: mode_str = "ir_var_system_value"; break;
222 case ir_var_temporary: mode_str = "ir_var_temporary"; break;
223 default:
224 unreachable("Invalid variable mode");
225 }
226
227 if (ir->data.mode == ir_var_temporary) {
228 print_with_indent("ir_variable *const r%04X = body.make_temp(glsl_type::%s_type, \"%s\");\n",
229 my_index,
230 ir->type->name,
231 ir->name);
232 } else {
233 print_with_indent("ir_variable *const r%04X = new(mem_ctx) ir_variable(glsl_type::%s_type, \"%s\", %s);\n",
234 my_index,
235 ir->type->name,
236 ir->name,
237 mode_str);
238
239 switch (ir->data.mode) {
240 case ir_var_function_in:
241 case ir_var_function_out:
242 case ir_var_function_inout:
243 case ir_var_const_in:
244 print_with_indent("sig_parameters.push_tail(r%04X);\n", my_index);
245 break;
246 default:
247 print_with_indent("body.emit(r%04X);\n", my_index);
248 break;
249 }
250 }
251
252 return visit_continue;
253 }
254
255 void
256 ir_builder_print_visitor::print_without_declaration(const ir_dereference_variable *ir)
257 {
258 const struct hash_entry *const he =
259 _mesa_hash_table_search(index_map, ir->var);
260
261 print_without_indent("r%04X", (unsigned)(uintptr_t) he->data);
262 }
263
264 ir_visitor_status
265 ir_builder_print_visitor::visit(ir_dereference_variable *ir)
266 {
267 const struct hash_entry *const he =
268 _mesa_hash_table_search(index_map, ir->var);
269
270 if (he != NULL)
271 _mesa_hash_table_insert(index_map, ir, he->data);
272
273 return visit_continue;
274 }
275
276 ir_visitor_status
277 ir_builder_print_visitor::visit_enter(ir_function_signature *ir)
278 {
279 if (!ir->is_defined)
280 return visit_continue_with_parent;
281
282 print_with_indent("ir_function_signature *\n"
283 "%s(void *mem_ctx, builtin_available_predicate avail)\n"
284 "{\n",
285 ir->function_name());
286 indentation++;
287 print_with_indent("ir_function_signature *const sig =\n");
288 print_with_indent(" new(mem_ctx) ir_function_signature(glsl_type::%s_type, avail);\n",
289 ir->return_type->name);
290
291 print_with_indent("ir_factory body(&sig->body, mem_ctx);\n");
292 print_with_indent("sig->is_defined = true;\n\n");
293
294 if (!ir->parameters.is_empty())
295 print_with_indent("exec_list sig_parameters;\n\n");
296
297 return visit_continue;
298 }
299
300 ir_visitor_status
301 ir_builder_print_visitor::visit_leave(ir_function_signature *ir)
302 {
303 if (!ir->parameters.is_empty())
304 print_with_indent("sig->replace_parameters(&sig_parameters);\n");
305
306 print_with_indent("return sig;\n");
307 indentation--;
308 print_with_indent("}\n");
309 return visit_continue;
310 }
311
312 void
313 ir_builder_print_visitor::print_without_declaration(const ir_constant *ir)
314 {
315 if (ir->type->is_scalar()) {
316 switch (ir->type->base_type) {
317 case GLSL_TYPE_UINT:
318 print_without_indent("body.constant(%uu)", ir->value.u[0]);
319 return;
320 case GLSL_TYPE_INT:
321 print_without_indent("body.constant(int(%d))", ir->value.i[0]);
322 return;
323 case GLSL_TYPE_FLOAT:
324 print_without_indent("body.constant(%ff)", ir->value.f[0]);
325 return;
326 case GLSL_TYPE_BOOL:
327 print_without_indent("body.constant(%s)",
328 ir->value.i[0] != 0 ? "true" : "false");
329 return;
330 default:
331 break;
332 }
333 }
334
335 ir_constant_data all_zero;
336 memset(&all_zero, 0, sizeof(all_zero));
337
338 if (memcmp(&ir->value, &all_zero, sizeof(all_zero)) == 0) {
339 print_without_indent("ir_constant::zero(mem_ctx, glsl_type::%s_type)",
340 ir->type->name);
341 }
342 }
343
344 ir_visitor_status
345 ir_builder_print_visitor::visit(ir_constant *ir)
346 {
347 const unsigned my_index = next_ir_index++;
348
349 _mesa_hash_table_insert(index_map, ir, (void *)(uintptr_t) my_index);
350
351 if (ir->type == glsl_type::uint_type ||
352 ir->type == glsl_type::int_type ||
353 ir->type == glsl_type::float_type ||
354 ir->type == glsl_type::bool_type) {
355 print_with_indent("ir_constant *const r%04X = ", my_index);
356 print_without_declaration(ir);
357 print_without_indent(";\n");
358 return visit_continue;
359 }
360
361 ir_constant_data all_zero;
362 memset(&all_zero, 0, sizeof(all_zero));
363
364 if (memcmp(&ir->value, &all_zero, sizeof(all_zero)) == 0) {
365 print_with_indent("ir_constant *const r%04X = ", my_index);
366 print_without_declaration(ir);
367 print_without_indent(";\n");
368 } else {
369 print_with_indent("ir_constant_data r%04X_data;\n", my_index);
370 print_with_indent("memset(&r%04X_data, 0, sizeof(ir_constant_data));\n",
371 my_index);
372 for (unsigned i = 0; i < 16; i++) {
373 switch (ir->type->base_type) {
374 case GLSL_TYPE_UINT:
375 if (ir->value.u[i] != 0)
376 print_without_indent("r%04X_data.u[%u] = %u;\n",
377 my_index, i, ir->value.u[i]);
378 break;
379 case GLSL_TYPE_INT:
380 if (ir->value.i[i] != 0)
381 print_without_indent("r%04X_data.i[%u] = %i;\n",
382 my_index, i, ir->value.i[i]);
383 break;
384 case GLSL_TYPE_FLOAT:
385 if (ir->value.u[i] != 0)
386 print_without_indent("r%04X_data.u[%u] = 0x%08x; /* %f */\n",
387 my_index,
388 i,
389 ir->value.u[i],
390 ir->value.f[i]);
391 break;
392 case GLSL_TYPE_DOUBLE: {
393 uint64_t v;
394
395 STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
396
397 memcpy(&v, &ir->value.d[i], sizeof(v));
398 if (v != 0)
399 /* FIXME: This won't actually work until ARB_gpu_shader_int64
400 * support lands.
401 */
402 print_without_indent("r%04X_data.u64[%u] = 0x%016" PRIx64 "; /* %g */\n",
403 my_index, i, v, ir->value.d[i]);
404 break;
405 }
406 case GLSL_TYPE_BOOL:
407 if (ir->value.u[i] != 0)
408 print_without_indent("r%04X_data.u[%u] = 1;\n", my_index, i);
409 break;
410 default:
411 unreachable("Invalid constant type");
412 }
413 }
414
415 print_with_indent("ir_constant *const r%04X = new(mem_ctx) ir_constant(glsl_type::%s_type, &r%04X_data);\n",
416 my_index,
417 ir->type->name,
418 my_index);
419 }
420
421 return visit_continue;
422 }
423
424 void
425 ir_builder_print_visitor::print_without_declaration(const ir_swizzle *ir)
426 {
427 const struct hash_entry *const he =
428 _mesa_hash_table_search(index_map, ir->val);
429
430 if (ir->mask.num_components == 1) {
431 static const char swiz[4] = { 'x', 'y', 'z', 'w' };
432
433 if (is_simple_operand(ir->val)) {
434 print_without_indent("swizzle_%c(", swiz[ir->mask.x]);
435 print_without_declaration(ir->val);
436 print_without_indent(")");
437 } else {
438 print_without_indent("swizzle_%c(r%04X)",
439 swiz[ir->mask.x],
440 (unsigned)(uintptr_t) he->data);
441 }
442 } else {
443 static const char swiz[4] = { 'X', 'Y', 'Z', 'W' };
444
445 print_without_indent("swizzle(r%04X, MAKE_SWIZZLE4(SWIZZLE_%c, SWIZZLE_%c, SWIZZLE_%c, SWIZZLE_%c), %u)",
446 (unsigned)(uintptr_t) he->data,
447 swiz[ir->mask.x],
448 swiz[ir->mask.y],
449 swiz[ir->mask.z],
450 swiz[ir->mask.w],
451 ir->mask.num_components);
452 }
453 }
454
455 ir_visitor_status
456 ir_builder_print_visitor::visit_leave(ir_swizzle *ir)
457 {
458 const unsigned my_index = next_ir_index++;
459
460 _mesa_hash_table_insert(index_map, ir, (void *)(uintptr_t) my_index);
461
462 print_with_indent("ir_swizzle *const r%04X = ", my_index);
463 print_without_declaration(ir);
464 print_without_indent(";\n");
465
466 return visit_continue;
467 }
468
469 ir_visitor_status
470 ir_builder_print_visitor::visit_enter(ir_assignment *ir)
471 {
472 ir_expression *const rhs_expr = ir->rhs->as_expression();
473
474 if (!is_simple_operand(ir->rhs) && rhs_expr == NULL)
475 return visit_continue;
476
477 if (rhs_expr != NULL) {
478 const unsigned num_op = rhs_expr->get_num_operands();
479
480 for (unsigned i = 0; i < num_op; i++) {
481 if (is_simple_operand(rhs_expr->operands[i]))
482 continue;
483
484 rhs_expr->operands[i]->accept(this);
485 }
486 }
487
488 ir_visitor_status s;
489
490 this->in_assignee = true;
491 s = ir->lhs->accept(this);
492 this->in_assignee = false;
493 if (s != visit_continue)
494 return (s == visit_continue_with_parent) ? visit_continue : s;
495
496 assert(ir->condition == NULL);
497
498 const struct hash_entry *const he_lhs =
499 _mesa_hash_table_search(index_map, ir->lhs);
500
501 print_with_indent("body.emit(assign(r%04X, ",
502 (unsigned)(uintptr_t) he_lhs->data);
503 print_without_declaration(ir->rhs);
504 print_without_indent(", 0x%02x));\n\n", ir->write_mask);
505
506 return visit_continue_with_parent;
507 }
508
509 ir_visitor_status
510 ir_builder_print_visitor::visit_leave(ir_assignment *ir)
511 {
512 const struct hash_entry *const he_lhs =
513 _mesa_hash_table_search(index_map, ir->lhs);
514
515 const struct hash_entry *const he_rhs =
516 _mesa_hash_table_search(index_map, ir->rhs);
517
518 assert(ir->condition == NULL);
519
520 print_with_indent("body.emit(assign(r%04X, r%04X, 0x%02x));\n\n",
521 (unsigned)(uintptr_t) he_lhs->data,
522 (unsigned)(uintptr_t) he_rhs->data,
523 ir->write_mask);
524
525 return visit_continue;
526 }
527
528 void
529 ir_builder_print_visitor::print_without_declaration(const ir_expression *ir)
530 {
531 const unsigned num_op = ir->get_num_operands();
532
533 static const char *const arity[] = {
534 "", "unop", "binop", "triop", "quadop"
535 };
536
537 switch (ir->operation) {
538 case ir_unop_neg:
539 case ir_binop_add:
540 case ir_binop_sub:
541 case ir_binop_mul:
542 case ir_binop_imul_high:
543 case ir_binop_less:
544 case ir_binop_greater:
545 case ir_binop_lequal:
546 case ir_binop_gequal:
547 case ir_binop_equal:
548 case ir_binop_nequal:
549 case ir_binop_lshift:
550 case ir_binop_rshift:
551 case ir_binop_bit_and:
552 case ir_binop_bit_xor:
553 case ir_binop_bit_or:
554 case ir_binop_logic_and:
555 case ir_binop_logic_xor:
556 case ir_binop_logic_or:
557 print_without_indent("%s(",
558 ir_expression_operation_enum_strings[ir->operation]);
559 break;
560 default:
561 print_without_indent("expr(ir_%s_%s, ",
562 arity[num_op],
563 ir_expression_operation_enum_strings[ir->operation]);
564 break;
565 }
566
567 for (unsigned i = 0; i < num_op; i++) {
568 if (is_simple_operand(ir->operands[i]))
569 print_without_declaration(ir->operands[i]);
570 else {
571 const struct hash_entry *const he =
572 _mesa_hash_table_search(index_map, ir->operands[i]);
573
574 print_without_indent("r%04X", (unsigned)(uintptr_t) he->data);
575 }
576
577 if (i < num_op - 1)
578 print_without_indent(", ");
579 }
580
581 print_without_indent(")");
582 }
583
584 ir_visitor_status
585 ir_builder_print_visitor::visit_enter(ir_expression *ir)
586 {
587 const unsigned num_op = ir->get_num_operands();
588
589 for (unsigned i = 0; i < num_op; i++) {
590 if (is_simple_operand(ir->operands[i]))
591 continue;
592
593 ir->operands[i]->accept(this);
594 }
595
596 const unsigned my_index = next_ir_index++;
597
598 _mesa_hash_table_insert(index_map, ir, (void *)(uintptr_t) my_index);
599
600 print_with_indent("ir_expression *const r%04X = ", my_index);
601 print_without_declaration(ir);
602 print_without_indent(";\n");
603
604 return visit_continue_with_parent;
605 }
606
607 ir_visitor_status
608 ir_builder_print_visitor::visit_enter(ir_if *ir)
609 {
610 const unsigned my_index = next_ir_index++;
611
612 print_with_indent("/* IF CONDITION */\n");
613
614 ir_visitor_status s = ir->condition->accept(this);
615 if (s != visit_continue)
616 return (s == visit_continue_with_parent) ? visit_continue : s;
617
618 const struct hash_entry *const he =
619 _mesa_hash_table_search(index_map, ir->condition);
620
621 print_with_indent("ir_if *f%04X = new(mem_ctx) ir_if(operand(r%04X).val);\n",
622 my_index,
623 (unsigned)(uintptr_t) he->data);
624 print_with_indent("exec_list *const f%04X_parent_instructions = body.instructions;\n\n",
625 my_index);
626
627 indentation++;
628 print_with_indent("/* THEN INSTRUCTIONS */\n");
629 print_with_indent("body.instructions = &f%04X->then_instructions;\n\n",
630 my_index);
631
632 if (s != visit_continue_with_parent) {
633 s = visit_list_elements(this, &ir->then_instructions);
634 if (s == visit_stop)
635 return s;
636 }
637
638 print_without_indent("\n");
639
640 if (!ir->else_instructions.is_empty()) {
641 print_with_indent("/* ELSE INSTRUCTIONS */\n");
642 print_with_indent("body.instructions = &f%04X->else_instructions;\n\n",
643 my_index);
644
645 if (s != visit_continue_with_parent) {
646 s = visit_list_elements(this, &ir->else_instructions);
647 if (s == visit_stop)
648 return s;
649 }
650
651 print_without_indent("\n");
652 }
653
654 indentation--;
655
656 print_with_indent("body.instructions = f%04X_parent_instructions;\n",
657 my_index);
658 print_with_indent("body.emit(f%04X);\n\n",
659 my_index);
660 print_with_indent("/* END IF */\n\n");
661
662 return visit_continue_with_parent;
663 }
664
665 ir_visitor_status
666 ir_builder_print_visitor::visit_leave(ir_return *ir)
667 {
668 const struct hash_entry *const he =
669 _mesa_hash_table_search(index_map, ir->value);
670
671 print_with_indent("body.emit(ret(r%04X));\n\n",
672 (unsigned)(uintptr_t) he->data);
673
674 return visit_continue;
675 }
676
677 ir_visitor_status
678 ir_builder_print_visitor::visit_leave(ir_call *ir)
679 {
680 const unsigned my_index = next_ir_index++;
681
682 print_without_indent("\n");
683 print_with_indent("/* CALL %s */\n", ir->callee_name());
684 print_with_indent("exec_list r%04X_parameters;\n", my_index);
685
686 foreach_in_list(ir_dereference_variable, param, &ir->actual_parameters) {
687 const struct hash_entry *const he =
688 _mesa_hash_table_search(index_map, param);
689
690 print_with_indent("r%04X_parameters.push_tail(operand(r%04X).val);\n",
691 my_index,
692 (unsigned)(uintptr_t) he->data);
693 }
694
695 char return_deref_string[32];
696 if (ir->return_deref) {
697 const struct hash_entry *const he =
698 _mesa_hash_table_search(index_map, ir->return_deref);
699
700 snprintf(return_deref_string, sizeof(return_deref_string),
701 "operand(r%04X).val",
702 (unsigned)(uintptr_t) he->data);
703 } else {
704 strcpy(return_deref_string, "NULL");
705 }
706
707 print_with_indent("body.emit(new(mem_ctx) ir_call(shader->symbols->get_function(\"%s\"),\n",
708 ir->callee_name());
709 print_with_indent(" %s, &r%04X_parameters);\n\n",
710 return_deref_string,
711 my_index);
712 return visit_continue;
713 }
714
715 ir_visitor_status
716 ir_builder_print_visitor::visit_enter(ir_loop *ir)
717 {
718 const unsigned my_index = next_ir_index++;
719
720 _mesa_hash_table_insert(index_map, ir, (void *)(uintptr_t) my_index);
721
722 print_with_indent("/* LOOP BEGIN */\n");
723 print_with_indent("ir_loop *f%04X = new(mem_ctx) ir_loop();\n", my_index);
724 print_with_indent("exec_list *const f%04X_parent_instructions = body.instructions;\n\n",
725 my_index);
726
727 indentation++;
728
729 print_with_indent("body.instructions = &f%04X->body_instructions;\n\n",
730 my_index);
731
732 return visit_continue;
733 }
734
735 ir_visitor_status
736 ir_builder_print_visitor::visit_leave(ir_loop *ir)
737 {
738 const struct hash_entry *const he =
739 _mesa_hash_table_search(index_map, ir);
740
741 indentation--;
742
743 print_with_indent("/* LOOP END */\n\n");
744 print_with_indent("body.instructions = f%04X_parent_instructions;\n",
745 (unsigned)(uintptr_t) he->data);
746 print_with_indent("body.emit(f%04X);\n\n",
747 (unsigned)(uintptr_t) he->data);
748
749 return visit_continue;
750 }
751
752 ir_visitor_status
753 ir_builder_print_visitor::visit(ir_loop_jump *ir)
754 {
755 print_with_indent("body.emit(new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_%s));\n\n",
756 ir->is_break() ? "break" : "continue");
757 return visit_continue;
758 }