X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fir_print_visitor.cpp;h=bd398052c3facf4c0984b4d0d6d6d225c693933b;hb=153b8b35257fb5d68735b5e43e48b0cdb8b15170;hp=0aa0b0a5d32f3a7f0e54a37eb86aba174c0cd2be;hpb=0f68236a2487dbeb0396b996debcda595b0b54a1;p=mesa.git diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index 0aa0b0a5d32..bd398052c3f 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/src/glsl/ir_print_visitor.cpp @@ -24,211 +24,306 @@ #include "ir_print_visitor.h" #include "glsl_types.h" #include "glsl_parser_extras.h" +#include "main/macros.h" +#include "program/hash_table.h" -static void print_type(const glsl_type *t); +static void print_type(FILE *f, const glsl_type *t); void ir_instruction::print(void) const +{ + this->fprint(stdout); +} + +void +ir_instruction::fprint(FILE *f) const { ir_instruction *deconsted = const_cast(this); - ir_print_visitor v; + ir_print_visitor v(f); deconsted->accept(&v); } +extern "C" { void -_mesa_print_ir(exec_list *instructions, +_mesa_print_ir(FILE *f, exec_list *instructions, struct _mesa_glsl_parse_state *state) { if (state) { for (unsigned i = 0; i < state->num_user_structures; i++) { const glsl_type *const s = state->user_structures[i]; - printf("(structure (%s) (%s@%p) (%u) (\n", - s->name, s->name, (void *) s, s->length); + fprintf(f, "(structure (%s) (%s@%p) (%u) (\n", + s->name, s->name, (void *) s, s->length); for (unsigned j = 0; j < s->length; j++) { - printf("\t(("); - print_type(s->fields.structure[j].type); - printf(")(%s))\n", s->fields.structure[j].name); + fprintf(f, "\t(("); + print_type(f, s->fields.structure[j].type); + fprintf(f, ")(%s))\n", s->fields.structure[j].name); } - printf(")\n"); + fprintf(f, ")\n"); } } - printf("(\n"); - foreach_iter(exec_list_iterator, iter, *instructions) { - ir_instruction *ir = (ir_instruction *)iter.get(); - ir->print(); + fprintf(f, "(\n"); + foreach_in_list(ir_instruction, ir, instructions) { + ir->fprint(f); if (ir->ir_type != ir_type_function) - printf("\n"); + fprintf(f, "\n"); } - printf("\n)"); + fprintf(f, "\n)"); +} + +void +fprint_ir(FILE *f, const void *instruction) +{ + const ir_instruction *ir = (const ir_instruction *)instruction; + ir->fprint(f); } +} /* extern "C" */ + +ir_print_visitor::ir_print_visitor(FILE *f) + : f(f) +{ + indentation = 0; + printable_names = + hash_table_ctor(32, hash_table_pointer_hash, hash_table_pointer_compare); + symbols = _mesa_symbol_table_ctor(); + mem_ctx = ralloc_context(NULL); +} + +ir_print_visitor::~ir_print_visitor() +{ + hash_table_dtor(printable_names); + _mesa_symbol_table_dtor(symbols); + ralloc_free(mem_ctx); +} void ir_print_visitor::indent(void) { for (int i = 0; i < indentation; i++) - printf(" "); + fprintf(f, " "); +} + +const char * +ir_print_visitor::unique_name(ir_variable *var) +{ + /* var->name can be NULL in function prototypes when a type is given for a + * parameter but no name is given. In that case, just return an empty + * string. Don't worry about tracking the generated name in the printable + * names hash because this is the only scope where it can ever appear. + */ + if (var->name == NULL) { + static unsigned arg = 1; + return ralloc_asprintf(this->mem_ctx, "parameter@%u", arg++); + } + + /* Do we already have a name for this variable? */ + const char *name = (const char *) hash_table_find(this->printable_names, var); + if (name != NULL) + return name; + + /* If there's no conflict, just use the original name */ + if (_mesa_symbol_table_find_symbol(this->symbols, -1, var->name) == NULL) { + name = var->name; + } else { + static unsigned i = 1; + name = ralloc_asprintf(this->mem_ctx, "%s@%u", var->name, ++i); + } + hash_table_insert(this->printable_names, (void *) name, var); + _mesa_symbol_table_add_symbol(this->symbols, -1, name, var); + return name; } static void -print_type(const glsl_type *t) +print_type(FILE *f, const glsl_type *t) { if (t->base_type == GLSL_TYPE_ARRAY) { - printf("(array "); - print_type(t->fields.array); - printf(" %u)", t->length); + fprintf(f, "(array "); + print_type(f, t->fields.array); + fprintf(f, " %u)", t->length); } else if ((t->base_type == GLSL_TYPE_STRUCT) - && (strncmp("gl_", t->name, 3) != 0)) { - printf("%s@%p", t->name, (void *) t); + && !is_gl_identifier(t->name)) { + fprintf(f, "%s@%p", t->name, (void *) t); } else { - printf("%s", t->name); + fprintf(f, "%s", t->name); } } +void ir_print_visitor::visit(ir_rvalue *) +{ + fprintf(f, "error"); +} void ir_print_visitor::visit(ir_variable *ir) { - printf("(declare "); - - const char *const cent = (ir->centroid) ? "centroid " : ""; - const char *const inv = (ir->invariant) ? "invariant " : ""; - const char *const mode[] = { "", "uniform ", "in ", "out ", "inout ", - "temporary " }; - const char *const interp[] = { "", "flat", "noperspective" }; - - printf("(%s%s%s%s) ", - cent, inv, mode[ir->mode], interp[ir->interpolation]); - - print_type(ir->type); - printf(" %s@%p)", ir->name, (void *) ir); + fprintf(f, "(declare "); + + const char *const cent = (ir->data.centroid) ? "centroid " : ""; + const char *const samp = (ir->data.sample) ? "sample " : ""; + const char *const inv = (ir->data.invariant) ? "invariant " : ""; + const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ", + "in ", "out ", "inout ", + "const_in ", "sys ", "temporary " }; + STATIC_ASSERT(ARRAY_SIZE(mode) == ir_var_mode_count); + const char *const stream [] = {"", "stream1 ", "stream2 ", "stream3 "}; + const char *const interp[] = { "", "smooth", "flat", "noperspective" }; + STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT); + + fprintf(f, "(%s%s%s%s%s%s) ", + cent, samp, inv, mode[ir->data.mode], + stream[ir->data.stream], + interp[ir->data.interpolation]); + + print_type(f, ir->type); + fprintf(f, " %s)", unique_name(ir)); } void ir_print_visitor::visit(ir_function_signature *ir) { - printf("(signature "); + _mesa_symbol_table_push_scope(symbols); + fprintf(f, "(signature "); indentation++; - print_type(ir->return_type); - printf("\n"); + print_type(f, ir->return_type); + fprintf(f, "\n"); indent(); - printf("(parameters\n"); + fprintf(f, "(parameters\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->parameters) { - ir_variable *const inst = (ir_variable *) iter.get(); - + foreach_in_list(ir_variable, inst, &ir->parameters) { indent(); inst->accept(this); - printf("\n"); + fprintf(f, "\n"); } indentation--; indent(); - printf(")\n"); + fprintf(f, ")\n"); indent(); - printf("(\n"); + fprintf(f, "(\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->body) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - + foreach_in_list(ir_instruction, inst, &ir->body) { indent(); inst->accept(this); - printf("\n"); + fprintf(f, "\n"); } indentation--; indent(); - printf("))\n"); + fprintf(f, "))\n"); indentation--; + _mesa_symbol_table_pop_scope(symbols); } void ir_print_visitor::visit(ir_function *ir) { - printf("(function %s\n", ir->name); + fprintf(f, "(function %s\n", ir->name); indentation++; - foreach_iter(exec_list_iterator, iter, *ir) { - ir_function_signature *const sig = (ir_function_signature *) iter.get(); + foreach_in_list(ir_function_signature, sig, &ir->signatures) { indent(); sig->accept(this); - printf("\n"); + fprintf(f, "\n"); } indentation--; indent(); - printf(")\n\n"); + fprintf(f, ")\n\n"); } void ir_print_visitor::visit(ir_expression *ir) { - printf("(expression "); + fprintf(f, "(expression "); - print_type(ir->type); + print_type(f, ir->type); - printf(" %s ", ir->operator_string()); + fprintf(f, " %s ", ir->operator_string()); for (unsigned i = 0; i < ir->get_num_operands(); i++) { ir->operands[i]->accept(this); } - printf(") "); + fprintf(f, ") "); } void ir_print_visitor::visit(ir_texture *ir) { - printf("(%s ", ir->opcode_string()); + fprintf(f, "(%s ", ir->opcode_string()); + + print_type(f, ir->type); + fprintf(f, " "); ir->sampler->accept(this); - printf(" "); + fprintf(f, " "); - ir->coordinate->accept(this); + if (ir->op != ir_txs && ir->op != ir_query_levels) { + ir->coordinate->accept(this); - printf(" (%d %d %d) ", ir->offsets[0], ir->offsets[1], ir->offsets[2]); + fprintf(f, " "); - if (ir->op != ir_txf) { + if (ir->offset != NULL) { + ir->offset->accept(this); + } else { + fprintf(f, "0"); + } + + fprintf(f, " "); + } + + if (ir->op != ir_txf && ir->op != ir_txf_ms && + ir->op != ir_txs && ir->op != ir_tg4 && + ir->op != ir_query_levels) { if (ir->projector) ir->projector->accept(this); else - printf("1"); + fprintf(f, "1"); if (ir->shadow_comparitor) { - printf(" "); + fprintf(f, " "); ir->shadow_comparitor->accept(this); } else { - printf(" ()"); + fprintf(f, " ()"); } } - printf(" "); + fprintf(f, " "); switch (ir->op) { case ir_tex: + case ir_lod: + case ir_query_levels: break; case ir_txb: ir->lod_info.bias->accept(this); break; case ir_txl: case ir_txf: + case ir_txs: ir->lod_info.lod->accept(this); break; + case ir_txf_ms: + ir->lod_info.sample_index->accept(this); + break; case ir_txd: - printf("("); + fprintf(f, "("); ir->lod_info.grad.dPdx->accept(this); - printf(" "); + fprintf(f, " "); ir->lod_info.grad.dPdy->accept(this); - printf(")"); + fprintf(f, ")"); + break; + case ir_tg4: + ir->lod_info.component->accept(this); break; }; - printf(")"); + fprintf(f, ")"); } @@ -241,49 +336,46 @@ void ir_print_visitor::visit(ir_swizzle *ir) ir->mask.w, }; - printf("(swiz "); + fprintf(f, "(swiz "); for (unsigned i = 0; i < ir->mask.num_components; i++) { - printf("%c", "xyzw"[swiz[i]]); + fprintf(f, "%c", "xyzw"[swiz[i]]); } - printf(" "); + fprintf(f, " "); ir->val->accept(this); - printf(")"); + fprintf(f, ")"); } void ir_print_visitor::visit(ir_dereference_variable *ir) { ir_variable *var = ir->variable_referenced(); - printf("(var_ref %s@%p) ", var->name, (void *) var); + fprintf(f, "(var_ref %s) ", unique_name(var)); } void ir_print_visitor::visit(ir_dereference_array *ir) { - printf("(array_ref "); + fprintf(f, "(array_ref "); ir->array->accept(this); ir->array_index->accept(this); - printf(") "); + fprintf(f, ") "); } void ir_print_visitor::visit(ir_dereference_record *ir) { - printf("(record_ref "); + fprintf(f, "(record_ref "); ir->record->accept(this); - printf(" %s) ", ir->field); + fprintf(f, " %s) ", ir->field); } void ir_print_visitor::visit(ir_assignment *ir) { - printf("(assign "); + fprintf(f, "(assign "); if (ir->condition) ir->condition->accept(this); - else - printf("(constant bool (1))"); - char mask[5]; unsigned j = 0; @@ -296,24 +388,22 @@ void ir_print_visitor::visit(ir_assignment *ir) } mask[j] = '\0'; - printf(" (%s) ", mask); + fprintf(f, " (%s) ", mask); ir->lhs->accept(this); - printf(" "); + fprintf(f, " "); ir->rhs->accept(this); - printf(") "); + fprintf(f, ") "); } void ir_print_visitor::visit(ir_constant *ir) { - const glsl_type *const base_type = ir->type->get_base_type(); - - printf("(constant "); - print_type(ir->type); - printf(" ("); + fprintf(f, "(constant "); + print_type(f, ir->type); + fprintf(f, " ("); if (ir->type->is_array()) { for (unsigned i = 0; i < ir->type->length; i++) @@ -321,109 +411,116 @@ void ir_print_visitor::visit(ir_constant *ir) } else if (ir->type->is_record()) { ir_constant *value = (ir_constant *) ir->components.get_head(); for (unsigned i = 0; i < ir->type->length; i++) { - printf("(%s ", ir->type->fields.structure->name); + fprintf(f, "(%s ", ir->type->fields.structure[i].name); value->accept(this); - printf(")"); + fprintf(f, ")"); value = (ir_constant *) value->next; } } else { for (unsigned i = 0; i < ir->type->components(); i++) { if (i != 0) - printf(" "); - switch (base_type->base_type) { - case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break; - case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break; - case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break; - case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break; + fprintf(f, " "); + switch (ir->type->base_type) { + case GLSL_TYPE_UINT: fprintf(f, "%u", ir->value.u[i]); break; + case GLSL_TYPE_INT: fprintf(f, "%d", ir->value.i[i]); break; + case GLSL_TYPE_FLOAT: + if (ir->value.f[i] == 0.0f) + /* 0.0 == -0.0, so print with %f to get the proper sign. */ + fprintf(f, "%f", ir->value.f[i]); + else if (fabs(ir->value.f[i]) < 0.000001f) + fprintf(f, "%a", ir->value.f[i]); + else if (fabs(ir->value.f[i]) > 1000000.0f) + fprintf(f, "%e", ir->value.f[i]); + else + fprintf(f, "%f", ir->value.f[i]); + break; + case GLSL_TYPE_BOOL: fprintf(f, "%d", ir->value.b[i]); break; default: assert(0); } } } - printf(")) "); + fprintf(f, ")) "); } void ir_print_visitor::visit(ir_call *ir) { - printf("(call %s (", ir->callee_name()); - foreach_iter(exec_list_iterator, iter, *ir) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - - inst->accept(this); + fprintf(f, "(call %s ", ir->callee_name()); + if (ir->return_deref) + ir->return_deref->accept(this); + fprintf(f, " ("); + foreach_in_list(ir_rvalue, param, &ir->actual_parameters) { + param->accept(this); } - printf("))\n"); + fprintf(f, "))\n"); } void ir_print_visitor::visit(ir_return *ir) { - printf("(return"); + fprintf(f, "(return"); ir_rvalue *const value = ir->get_value(); if (value) { - printf(" "); + fprintf(f, " "); value->accept(this); } - printf(")"); + fprintf(f, ")"); } void ir_print_visitor::visit(ir_discard *ir) { - printf("(discard "); + fprintf(f, "(discard "); if (ir->condition != NULL) { - printf(" "); + fprintf(f, " "); ir->condition->accept(this); } - printf(")"); + fprintf(f, ")"); } void ir_print_visitor::visit(ir_if *ir) { - printf("(if "); + fprintf(f, "(if "); ir->condition->accept(this); - printf("(\n"); + fprintf(f, "(\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->then_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - + foreach_in_list(ir_instruction, inst, &ir->then_instructions) { indent(); inst->accept(this); - printf("\n"); + fprintf(f, "\n"); } indentation--; indent(); - printf(")\n"); + fprintf(f, ")\n"); indent(); if (!ir->else_instructions.is_empty()) { - printf("(\n"); + fprintf(f, "(\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->else_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - + foreach_in_list(ir_instruction, inst, &ir->else_instructions) { indent(); inst->accept(this); - printf("\n"); + fprintf(f, "\n"); } indentation--; indent(); - printf("))\n"); + fprintf(f, "))\n"); } else { - printf("())\n"); + fprintf(f, "())\n"); } } @@ -431,36 +528,39 @@ ir_print_visitor::visit(ir_if *ir) void ir_print_visitor::visit(ir_loop *ir) { - printf("(loop ("); - if (ir->counter != NULL) - ir->counter->accept(this); - printf(") ("); - if (ir->from != NULL) - ir->from->accept(this); - printf(") ("); - if (ir->to != NULL) - ir->to->accept(this); - printf(") ("); - if (ir->increment != NULL) - ir->increment->accept(this); - printf(") (\n"); + fprintf(f, "(loop (\n"); indentation++; - foreach_iter(exec_list_iterator, iter, ir->body_instructions) { - ir_instruction *const inst = (ir_instruction *) iter.get(); - + foreach_in_list(ir_instruction, inst, &ir->body_instructions) { indent(); inst->accept(this); - printf("\n"); + fprintf(f, "\n"); } indentation--; indent(); - printf("))\n"); + fprintf(f, "))\n"); } void ir_print_visitor::visit(ir_loop_jump *ir) { - printf("%s", ir->is_break() ? "break" : "continue"); + fprintf(f, "%s", ir->is_break() ? "break" : "continue"); +} + +void +ir_print_visitor::visit(ir_emit_vertex *ir) +{ + fprintf(f, "(emit-vertex "); + ir->stream->accept(this); + fprintf(f, ")\n"); +} + +void +ir_print_visitor::visit(ir_end_primitive *ir) +{ + fprintf(f, "(end-primitive "); + ir->stream->accept(this); + fprintf(f, ")\n"); + }