• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
28 static void print_type(const glsl_type *t);
29 
30 void
print(void) const31 ir_instruction::print(void) const
32 {
33    ir_instruction *deconsted = const_cast<ir_instruction *>(this);
34 
35    ir_print_visitor v;
36    deconsted->accept(&v);
37 }
38 
39 void
_mesa_print_ir(exec_list * instructions,struct _mesa_glsl_parse_state * state)40 _mesa_print_ir(exec_list *instructions,
41 	       struct _mesa_glsl_parse_state *state)
42 {
43    if (state) {
44       for (unsigned i = 0; i < state->num_user_structures; i++) {
45 	 const glsl_type *const s = state->user_structures[i];
46 
47 	 printf("(structure (%s) (%s@%p) (%u) (\n",
48 		s->name, s->name, (void *) s, s->length);
49 
50 	 for (unsigned j = 0; j < s->length; j++) {
51 	    printf("\t((");
52 	    print_type(s->fields.structure[j].type);
53 	    printf(")(%s))\n", s->fields.structure[j].name);
54 	 }
55 
56 	 printf(")\n");
57       }
58    }
59 
60    printf("(\n");
61    foreach_iter(exec_list_iterator, iter, *instructions) {
62       ir_instruction *ir = (ir_instruction *)iter.get();
63       ir->print();
64       if (ir->ir_type != ir_type_function)
65 	 printf("\n");
66    }
67    printf("\n)");
68 }
69 
70 
indent(void)71 void ir_print_visitor::indent(void)
72 {
73    for (int i = 0; i < indentation; i++)
74       printf("  ");
75 }
76 
77 static void
print_type(const glsl_type * t)78 print_type(const glsl_type *t)
79 {
80    if (t->base_type == GLSL_TYPE_ARRAY) {
81       printf("(array ");
82       print_type(t->fields.array);
83       printf(" %u)", t->length);
84    } else if ((t->base_type == GLSL_TYPE_STRUCT)
85 	      && (strncmp("gl_", t->name, 3) != 0)) {
86       printf("%s@%p", t->name, (void *) t);
87    } else {
88       printf("%s", t->name);
89    }
90 }
91 
92 
visit(ir_variable * ir)93 void ir_print_visitor::visit(ir_variable *ir)
94 {
95    printf("(declare ");
96 
97    const char *const cent = (ir->centroid) ? "centroid " : "";
98    const char *const inv = (ir->invariant) ? "invariant " : "";
99    const char *const mode[] = { "", "uniform ", "in ", "out ", "inout ",
100 			        "temporary " };
101    const char *const interp[] = { "", "flat", "noperspective" };
102 
103    printf("(%s%s%s%s) ",
104 	  cent, inv, mode[ir->mode], interp[ir->interpolation]);
105 
106    print_type(ir->type);
107    printf(" %s@%p)", ir->name, (void *) ir);
108 }
109 
110 
visit(ir_function_signature * ir)111 void ir_print_visitor::visit(ir_function_signature *ir)
112 {
113    printf("(signature ");
114    indentation++;
115 
116    print_type(ir->return_type);
117    printf("\n");
118    indent();
119 
120    printf("(parameters\n");
121    indentation++;
122 
123    foreach_iter(exec_list_iterator, iter, ir->parameters) {
124       ir_variable *const inst = (ir_variable *) iter.get();
125 
126       indent();
127       inst->accept(this);
128       printf("\n");
129    }
130    indentation--;
131 
132    indent();
133    printf(")\n");
134 
135    indent();
136 
137    printf("(\n");
138    indentation++;
139 
140    foreach_iter(exec_list_iterator, iter, ir->body) {
141       ir_instruction *const inst = (ir_instruction *) iter.get();
142 
143       indent();
144       inst->accept(this);
145       printf("\n");
146    }
147    indentation--;
148    indent();
149    printf("))\n");
150    indentation--;
151 }
152 
153 
visit(ir_function * ir)154 void ir_print_visitor::visit(ir_function *ir)
155 {
156    printf("(function %s\n", ir->name);
157    indentation++;
158    foreach_iter(exec_list_iterator, iter, *ir) {
159       ir_function_signature *const sig = (ir_function_signature *) iter.get();
160       indent();
161       sig->accept(this);
162       printf("\n");
163    }
164    indentation--;
165    indent();
166    printf(")\n\n");
167 }
168 
169 
visit(ir_expression * ir)170 void ir_print_visitor::visit(ir_expression *ir)
171 {
172    printf("(expression ");
173 
174    print_type(ir->type);
175 
176    printf(" %s ", ir->operator_string());
177 
178    for (unsigned i = 0; i < ir->get_num_operands(); i++) {
179       ir->operands[i]->accept(this);
180    }
181 
182    printf(") ");
183 }
184 
185 
visit(ir_texture * ir)186 void ir_print_visitor::visit(ir_texture *ir)
187 {
188    printf("(%s ", ir->opcode_string());
189 
190    ir->sampler->accept(this);
191    printf(" ");
192 
193    ir->coordinate->accept(this);
194 
195    printf(" (%d %d %d) ", ir->offsets[0], ir->offsets[1], ir->offsets[2]);
196 
197    if (ir->op != ir_txf) {
198       if (ir->projector)
199 	 ir->projector->accept(this);
200       else
201 	 printf("1");
202 
203       if (ir->shadow_comparitor) {
204 	 printf(" ");
205 	 ir->shadow_comparitor->accept(this);
206       } else {
207 	 printf(" ()");
208       }
209    }
210 
211    printf(" ");
212    switch (ir->op)
213    {
214    case ir_tex:
215       break;
216    case ir_txb:
217       ir->lod_info.bias->accept(this);
218       break;
219    case ir_txl:
220    case ir_txf:
221       ir->lod_info.lod->accept(this);
222       break;
223    case ir_txd:
224       printf("(");
225       ir->lod_info.grad.dPdx->accept(this);
226       printf(" ");
227       ir->lod_info.grad.dPdy->accept(this);
228       printf(")");
229       break;
230    };
231    printf(")");
232 }
233 
234 
visit(ir_swizzle * ir)235 void ir_print_visitor::visit(ir_swizzle *ir)
236 {
237    const unsigned swiz[4] = {
238       ir->mask.x,
239       ir->mask.y,
240       ir->mask.z,
241       ir->mask.w,
242    };
243 
244    printf("(swiz ");
245    for (unsigned i = 0; i < ir->mask.num_components; i++) {
246       printf("%c", "xyzw"[swiz[i]]);
247    }
248    printf(" ");
249    ir->val->accept(this);
250    printf(")");
251 }
252 
253 
visit(ir_dereference_variable * ir)254 void ir_print_visitor::visit(ir_dereference_variable *ir)
255 {
256    ir_variable *var = ir->variable_referenced();
257    printf("(var_ref %s@%p) ", var->name, (void *) var);
258 }
259 
260 
visit(ir_dereference_array * ir)261 void ir_print_visitor::visit(ir_dereference_array *ir)
262 {
263    printf("(array_ref ");
264    ir->array->accept(this);
265    ir->array_index->accept(this);
266    printf(") ");
267 }
268 
269 
visit(ir_dereference_record * ir)270 void ir_print_visitor::visit(ir_dereference_record *ir)
271 {
272    printf("(record_ref ");
273    ir->record->accept(this);
274    printf(" %s) ", ir->field);
275 }
276 
277 
visit(ir_assignment * ir)278 void ir_print_visitor::visit(ir_assignment *ir)
279 {
280    printf("(assign ");
281 
282    if (ir->condition)
283       ir->condition->accept(this);
284    else
285       printf("(constant bool (1))");
286 
287 
288    char mask[5];
289    unsigned j = 0;
290 
291    for (unsigned i = 0; i < 4; i++) {
292       if ((ir->write_mask & (1 << i)) != 0) {
293 	 mask[j] = "xyzw"[i];
294 	 j++;
295       }
296    }
297    mask[j] = '\0';
298 
299    printf(" (%s) ", mask);
300 
301    ir->lhs->accept(this);
302 
303    printf(" ");
304 
305    ir->rhs->accept(this);
306    printf(") ");
307 }
308 
309 
visit(ir_constant * ir)310 void ir_print_visitor::visit(ir_constant *ir)
311 {
312    const glsl_type *const base_type = ir->type->get_base_type();
313 
314    printf("(constant ");
315    print_type(ir->type);
316    printf(" (");
317 
318    if (ir->type->is_array()) {
319       for (unsigned i = 0; i < ir->type->length; i++)
320 	 ir->get_array_element(i)->accept(this);
321    } else if (ir->type->is_record()) {
322       ir_constant *value = (ir_constant *) ir->components.get_head();
323       for (unsigned i = 0; i < ir->type->length; i++) {
324 	 printf("(%s ", ir->type->fields.structure->name);
325 	 value->accept(this);
326 	 printf(")");
327 
328 	 value = (ir_constant *) value->next;
329       }
330    } else {
331       for (unsigned i = 0; i < ir->type->components(); i++) {
332 	 if (i != 0)
333 	    printf(" ");
334 	 switch (base_type->base_type) {
335 	 case GLSL_TYPE_UINT:  printf("%u", ir->value.u[i]); break;
336 	 case GLSL_TYPE_INT:   printf("%d", ir->value.i[i]); break;
337 	 case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
338 	 case GLSL_TYPE_BOOL:  printf("%d", ir->value.b[i]); break;
339 	 default: assert(0);
340 	 }
341       }
342    }
343    printf(")) ");
344 }
345 
346 
347 void
visit(ir_call * ir)348 ir_print_visitor::visit(ir_call *ir)
349 {
350    printf("(call %s (", ir->callee_name());
351    foreach_iter(exec_list_iterator, iter, *ir) {
352       ir_instruction *const inst = (ir_instruction *) iter.get();
353 
354       inst->accept(this);
355    }
356    printf("))\n");
357 }
358 
359 
360 void
visit(ir_return * ir)361 ir_print_visitor::visit(ir_return *ir)
362 {
363    printf("(return");
364 
365    ir_rvalue *const value = ir->get_value();
366    if (value) {
367       printf(" ");
368       value->accept(this);
369    }
370 
371    printf(")");
372 }
373 
374 
375 void
visit(ir_discard * ir)376 ir_print_visitor::visit(ir_discard *ir)
377 {
378    printf("(discard ");
379 
380    if (ir->condition != NULL) {
381       printf(" ");
382       ir->condition->accept(this);
383    }
384 
385    printf(")");
386 }
387 
388 
389 void
visit(ir_if * ir)390 ir_print_visitor::visit(ir_if *ir)
391 {
392    printf("(if ");
393    ir->condition->accept(this);
394 
395    printf("(\n");
396    indentation++;
397 
398    foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
399       ir_instruction *const inst = (ir_instruction *) iter.get();
400 
401       indent();
402       inst->accept(this);
403       printf("\n");
404    }
405 
406    indentation--;
407    indent();
408    printf(")\n");
409 
410    indent();
411    if (!ir->else_instructions.is_empty()) {
412       printf("(\n");
413       indentation++;
414 
415       foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
416 	 ir_instruction *const inst = (ir_instruction *) iter.get();
417 
418 	 indent();
419 	 inst->accept(this);
420 	 printf("\n");
421       }
422       indentation--;
423       indent();
424       printf("))\n");
425    } else {
426       printf("())\n");
427    }
428 }
429 
430 
431 void
visit(ir_loop * ir)432 ir_print_visitor::visit(ir_loop *ir)
433 {
434    printf("(loop (");
435    if (ir->counter != NULL)
436       ir->counter->accept(this);
437    printf(") (");
438    if (ir->from != NULL)
439       ir->from->accept(this);
440    printf(") (");
441    if (ir->to != NULL)
442       ir->to->accept(this);
443    printf(") (");
444    if (ir->increment != NULL)
445       ir->increment->accept(this);
446    printf(") (\n");
447    indentation++;
448 
449    foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
450       ir_instruction *const inst = (ir_instruction *) iter.get();
451 
452       indent();
453       inst->accept(this);
454       printf("\n");
455    }
456    indentation--;
457    indent();
458    printf("))\n");
459 }
460 
461 
462 void
visit(ir_loop_jump * ir)463 ir_print_visitor::visit(ir_loop_jump *ir)
464 {
465    printf("%s", ir->is_break() ? "break" : "continue");
466 }
467