glsl/loops: Get rid of lower_bounded_loops and ir_loop::normative_bound.
[mesa.git] / src / glsl / ir_print_visitor.cpp
1 /*
2 * Copyright © 2010 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 "ir_print_visitor.h"
25 #include "glsl_types.h"
26 #include "glsl_parser_extras.h"
27 #include "main/macros.h"
28 #include "program/hash_table.h"
29
30 static void print_type(const glsl_type *t);
31
32 void
33 ir_instruction::print(void) const
34 {
35 ir_instruction *deconsted = const_cast<ir_instruction *>(this);
36
37 ir_print_visitor v;
38 deconsted->accept(&v);
39 }
40
41 extern "C" {
42 void
43 _mesa_print_ir(exec_list *instructions,
44 struct _mesa_glsl_parse_state *state)
45 {
46 if (state) {
47 for (unsigned i = 0; i < state->num_user_structures; i++) {
48 const glsl_type *const s = state->user_structures[i];
49
50 printf("(structure (%s) (%s@%p) (%u) (\n",
51 s->name, s->name, (void *) s, s->length);
52
53 for (unsigned j = 0; j < s->length; j++) {
54 printf("\t((");
55 print_type(s->fields.structure[j].type);
56 printf(")(%s))\n", s->fields.structure[j].name);
57 }
58
59 printf(")\n");
60 }
61 }
62
63 printf("(\n");
64 foreach_iter(exec_list_iterator, iter, *instructions) {
65 ir_instruction *ir = (ir_instruction *)iter.get();
66 ir->print();
67 if (ir->ir_type != ir_type_function)
68 printf("\n");
69 }
70 printf("\n)");
71 }
72
73 } /* extern "C" */
74
75 ir_print_visitor::ir_print_visitor()
76 {
77 indentation = 0;
78 printable_names =
79 hash_table_ctor(32, hash_table_pointer_hash, hash_table_pointer_compare);
80 symbols = _mesa_symbol_table_ctor();
81 mem_ctx = ralloc_context(NULL);
82 }
83
84 ir_print_visitor::~ir_print_visitor()
85 {
86 hash_table_dtor(printable_names);
87 _mesa_symbol_table_dtor(symbols);
88 ralloc_free(mem_ctx);
89 }
90
91 void ir_print_visitor::indent(void)
92 {
93 for (int i = 0; i < indentation; i++)
94 printf(" ");
95 }
96
97 const char *
98 ir_print_visitor::unique_name(ir_variable *var)
99 {
100 /* var->name can be NULL in function prototypes when a type is given for a
101 * parameter but no name is given. In that case, just return an empty
102 * string. Don't worry about tracking the generated name in the printable
103 * names hash because this is the only scope where it can ever appear.
104 */
105 if (var->name == NULL) {
106 static unsigned arg = 1;
107 return ralloc_asprintf(this->mem_ctx, "parameter@%u", arg++);
108 }
109
110 /* Do we already have a name for this variable? */
111 const char *name = (const char *) hash_table_find(this->printable_names, var);
112 if (name != NULL)
113 return name;
114
115 /* If there's no conflict, just use the original name */
116 if (_mesa_symbol_table_find_symbol(this->symbols, -1, var->name) == NULL) {
117 name = var->name;
118 } else {
119 static unsigned i = 1;
120 name = ralloc_asprintf(this->mem_ctx, "%s@%u", var->name, ++i);
121 }
122 hash_table_insert(this->printable_names, (void *) name, var);
123 _mesa_symbol_table_add_symbol(this->symbols, -1, name, var);
124 return name;
125 }
126
127 static void
128 print_type(const glsl_type *t)
129 {
130 if (t->base_type == GLSL_TYPE_ARRAY) {
131 printf("(array ");
132 print_type(t->fields.array);
133 printf(" %u)", t->length);
134 } else if ((t->base_type == GLSL_TYPE_STRUCT)
135 && (strncmp("gl_", t->name, 3) != 0)) {
136 printf("%s@%p", t->name, (void *) t);
137 } else {
138 printf("%s", t->name);
139 }
140 }
141
142 void ir_print_visitor::visit(ir_rvalue *ir)
143 {
144 printf("error");
145 }
146
147 void ir_print_visitor::visit(ir_variable *ir)
148 {
149 printf("(declare ");
150
151 const char *const cent = (ir->centroid) ? "centroid " : "";
152 const char *const samp = (ir->sample) ? "sample " : "";
153 const char *const inv = (ir->invariant) ? "invariant " : "";
154 const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ",
155 "in ", "out ", "inout ",
156 "const_in ", "sys ", "temporary " };
157 STATIC_ASSERT(ARRAY_SIZE(mode) == ir_var_mode_count);
158 const char *const interp[] = { "", "smooth", "flat", "noperspective" };
159 STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
160
161 printf("(%s%s%s%s%s) ",
162 cent, samp, inv, mode[ir->mode], interp[ir->interpolation]);
163
164 print_type(ir->type);
165 printf(" %s)", unique_name(ir));
166 }
167
168
169 void ir_print_visitor::visit(ir_function_signature *ir)
170 {
171 _mesa_symbol_table_push_scope(symbols);
172 printf("(signature ");
173 indentation++;
174
175 print_type(ir->return_type);
176 printf("\n");
177 indent();
178
179 printf("(parameters\n");
180 indentation++;
181
182 foreach_iter(exec_list_iterator, iter, ir->parameters) {
183 ir_variable *const inst = (ir_variable *) iter.get();
184
185 indent();
186 inst->accept(this);
187 printf("\n");
188 }
189 indentation--;
190
191 indent();
192 printf(")\n");
193
194 indent();
195
196 printf("(\n");
197 indentation++;
198
199 foreach_iter(exec_list_iterator, iter, ir->body) {
200 ir_instruction *const inst = (ir_instruction *) iter.get();
201
202 indent();
203 inst->accept(this);
204 printf("\n");
205 }
206 indentation--;
207 indent();
208 printf("))\n");
209 indentation--;
210 _mesa_symbol_table_pop_scope(symbols);
211 }
212
213
214 void ir_print_visitor::visit(ir_function *ir)
215 {
216 printf("(function %s\n", ir->name);
217 indentation++;
218 foreach_iter(exec_list_iterator, iter, *ir) {
219 ir_function_signature *const sig = (ir_function_signature *) iter.get();
220 indent();
221 sig->accept(this);
222 printf("\n");
223 }
224 indentation--;
225 indent();
226 printf(")\n\n");
227 }
228
229
230 void ir_print_visitor::visit(ir_expression *ir)
231 {
232 printf("(expression ");
233
234 print_type(ir->type);
235
236 printf(" %s ", ir->operator_string());
237
238 for (unsigned i = 0; i < ir->get_num_operands(); i++) {
239 ir->operands[i]->accept(this);
240 }
241
242 printf(") ");
243 }
244
245
246 void ir_print_visitor::visit(ir_texture *ir)
247 {
248 printf("(%s ", ir->opcode_string());
249
250 print_type(ir->type);
251 printf(" ");
252
253 ir->sampler->accept(this);
254 printf(" ");
255
256 if (ir->op != ir_txs && ir->op != ir_query_levels) {
257 ir->coordinate->accept(this);
258
259 printf(" ");
260
261 if (ir->offset != NULL) {
262 ir->offset->accept(this);
263 } else {
264 printf("0");
265 }
266
267 printf(" ");
268 }
269
270 if (ir->op != ir_txf && ir->op != ir_txf_ms &&
271 ir->op != ir_txs && ir->op != ir_tg4 &&
272 ir->op != ir_query_levels) {
273 if (ir->projector)
274 ir->projector->accept(this);
275 else
276 printf("1");
277
278 if (ir->shadow_comparitor) {
279 printf(" ");
280 ir->shadow_comparitor->accept(this);
281 } else {
282 printf(" ()");
283 }
284 }
285
286 printf(" ");
287 switch (ir->op)
288 {
289 case ir_tex:
290 case ir_lod:
291 case ir_query_levels:
292 break;
293 case ir_txb:
294 ir->lod_info.bias->accept(this);
295 break;
296 case ir_txl:
297 case ir_txf:
298 case ir_txs:
299 ir->lod_info.lod->accept(this);
300 break;
301 case ir_txf_ms:
302 ir->lod_info.sample_index->accept(this);
303 break;
304 case ir_txd:
305 printf("(");
306 ir->lod_info.grad.dPdx->accept(this);
307 printf(" ");
308 ir->lod_info.grad.dPdy->accept(this);
309 printf(")");
310 break;
311 case ir_tg4:
312 ir->lod_info.component->accept(this);
313 break;
314 };
315 printf(")");
316 }
317
318
319 void ir_print_visitor::visit(ir_swizzle *ir)
320 {
321 const unsigned swiz[4] = {
322 ir->mask.x,
323 ir->mask.y,
324 ir->mask.z,
325 ir->mask.w,
326 };
327
328 printf("(swiz ");
329 for (unsigned i = 0; i < ir->mask.num_components; i++) {
330 printf("%c", "xyzw"[swiz[i]]);
331 }
332 printf(" ");
333 ir->val->accept(this);
334 printf(")");
335 }
336
337
338 void ir_print_visitor::visit(ir_dereference_variable *ir)
339 {
340 ir_variable *var = ir->variable_referenced();
341 printf("(var_ref %s) ", unique_name(var));
342 }
343
344
345 void ir_print_visitor::visit(ir_dereference_array *ir)
346 {
347 printf("(array_ref ");
348 ir->array->accept(this);
349 ir->array_index->accept(this);
350 printf(") ");
351 }
352
353
354 void ir_print_visitor::visit(ir_dereference_record *ir)
355 {
356 printf("(record_ref ");
357 ir->record->accept(this);
358 printf(" %s) ", ir->field);
359 }
360
361
362 void ir_print_visitor::visit(ir_assignment *ir)
363 {
364 printf("(assign ");
365
366 if (ir->condition)
367 ir->condition->accept(this);
368
369 char mask[5];
370 unsigned j = 0;
371
372 for (unsigned i = 0; i < 4; i++) {
373 if ((ir->write_mask & (1 << i)) != 0) {
374 mask[j] = "xyzw"[i];
375 j++;
376 }
377 }
378 mask[j] = '\0';
379
380 printf(" (%s) ", mask);
381
382 ir->lhs->accept(this);
383
384 printf(" ");
385
386 ir->rhs->accept(this);
387 printf(") ");
388 }
389
390
391 void ir_print_visitor::visit(ir_constant *ir)
392 {
393 printf("(constant ");
394 print_type(ir->type);
395 printf(" (");
396
397 if (ir->type->is_array()) {
398 for (unsigned i = 0; i < ir->type->length; i++)
399 ir->get_array_element(i)->accept(this);
400 } else if (ir->type->is_record()) {
401 ir_constant *value = (ir_constant *) ir->components.get_head();
402 for (unsigned i = 0; i < ir->type->length; i++) {
403 printf("(%s ", ir->type->fields.structure[i].name);
404 value->accept(this);
405 printf(")");
406
407 value = (ir_constant *) value->next;
408 }
409 } else {
410 for (unsigned i = 0; i < ir->type->components(); i++) {
411 if (i != 0)
412 printf(" ");
413 switch (ir->type->base_type) {
414 case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break;
415 case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break;
416 case GLSL_TYPE_FLOAT:
417 if (ir->value.f[i] == 0.0f)
418 /* 0.0 == -0.0, so print with %f to get the proper sign. */
419 printf("%.1f", ir->value.f[i]);
420 else if (fabs(ir->value.f[i]) < 0.000001f)
421 printf("%a", ir->value.f[i]);
422 else if (fabs(ir->value.f[i]) > 1000000.0f)
423 printf("%e", ir->value.f[i]);
424 else
425 printf("%f", ir->value.f[i]);
426 break;
427 case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break;
428 default: assert(0);
429 }
430 }
431 }
432 printf(")) ");
433 }
434
435
436 void
437 ir_print_visitor::visit(ir_call *ir)
438 {
439 printf("(call %s ", ir->callee_name());
440 if (ir->return_deref)
441 ir->return_deref->accept(this);
442 printf(" (");
443 foreach_iter(exec_list_iterator, iter, *ir) {
444 ir_instruction *const inst = (ir_instruction *) iter.get();
445
446 inst->accept(this);
447 }
448 printf("))\n");
449 }
450
451
452 void
453 ir_print_visitor::visit(ir_return *ir)
454 {
455 printf("(return");
456
457 ir_rvalue *const value = ir->get_value();
458 if (value) {
459 printf(" ");
460 value->accept(this);
461 }
462
463 printf(")");
464 }
465
466
467 void
468 ir_print_visitor::visit(ir_discard *ir)
469 {
470 printf("(discard ");
471
472 if (ir->condition != NULL) {
473 printf(" ");
474 ir->condition->accept(this);
475 }
476
477 printf(")");
478 }
479
480
481 void
482 ir_print_visitor::visit(ir_if *ir)
483 {
484 printf("(if ");
485 ir->condition->accept(this);
486
487 printf("(\n");
488 indentation++;
489
490 foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
491 ir_instruction *const inst = (ir_instruction *) iter.get();
492
493 indent();
494 inst->accept(this);
495 printf("\n");
496 }
497
498 indentation--;
499 indent();
500 printf(")\n");
501
502 indent();
503 if (!ir->else_instructions.is_empty()) {
504 printf("(\n");
505 indentation++;
506
507 foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
508 ir_instruction *const inst = (ir_instruction *) iter.get();
509
510 indent();
511 inst->accept(this);
512 printf("\n");
513 }
514 indentation--;
515 indent();
516 printf("))\n");
517 } else {
518 printf("())\n");
519 }
520 }
521
522
523 void
524 ir_print_visitor::visit(ir_loop *ir)
525 {
526 printf("(loop (\n");
527 indentation++;
528
529 foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
530 ir_instruction *const inst = (ir_instruction *) iter.get();
531
532 indent();
533 inst->accept(this);
534 printf("\n");
535 }
536 indentation--;
537 indent();
538 printf("))\n");
539 }
540
541
542 void
543 ir_print_visitor::visit(ir_loop_jump *ir)
544 {
545 printf("%s", ir->is_break() ? "break" : "continue");
546 }
547
548 void
549 ir_print_visitor::visit(ir_emit_vertex *ir)
550 {
551 printf("(emit-vertex)");
552 }
553
554 void
555 ir_print_visitor::visit(ir_end_primitive *ir)
556 {
557 printf("(end-primitive)");
558 }