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