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