diff options
author | Kenneth Graunke <kenneth@whitecape.org> | 2011-03-25 10:59:46 -0700 |
---|---|---|
committer | Kenneth Graunke <kenneth@whitecape.org> | 2011-03-25 16:31:53 -0700 |
commit | 56ef62d9885f805bbfb2243dc860ff425d5b4d3b (patch) | |
tree | 746cd618acde71f416a5a8f3ee71860bdcbe87f8 | |
parent | eb0dd370945b9e3f5eb548a1a4a8184bb0e604fc (diff) |
glsl: Generate readable unique names at print time.
Since GLSL IR allows multiple ir_variables to share the same name, we
need to generate unique names when printing the IR. Previously, we
always used %s@%p, appending the ir_variable's memory address.
While this worked, it had two drawbacks:
- When there aren't duplicates, the extra "@0x669a3e88" is useless
and makes the code harder to read.
- Real duplicates were hard to tell apart:
channel_expressions@0x6699e3c8 vs. channel_expressions@0x6699ddd8
We now append @2, @3, @4, and so on, but only where necessary to
distinguish duplicates. Since we only do this at print time, any
performance impact is irrelevant.
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Ian Romanick <idr@freedesktop.org>
-rw-r--r-- | src/glsl/ir_print_visitor.cpp | 45 | ||||
-rw-r--r-- | src/glsl/ir_print_visitor.h | 29 |
2 files changed, 63 insertions, 11 deletions
diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index a84f8dfc8a1..02f3d814926 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/src/glsl/ir_print_visitor.cpp @@ -25,6 +25,10 @@ #include "glsl_types.h" #include "glsl_parser_extras.h" +extern "C" { +#include "program/hash_table.h" +} + static void print_type(const glsl_type *t); void @@ -67,6 +71,21 @@ _mesa_print_ir(exec_list *instructions, printf("\n)"); } +ir_print_visitor::ir_print_visitor() +{ + 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) { @@ -74,6 +93,26 @@ void ir_print_visitor::indent(void) printf(" "); } +const char * +ir_print_visitor::unique_name(ir_variable *var) +{ + /* 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) { @@ -104,12 +143,13 @@ void ir_print_visitor::visit(ir_variable *ir) cent, inv, mode[ir->mode], interp[ir->interpolation]); print_type(ir->type); - printf(" %s@%p)", ir->name, (void *) ir); + printf(" %s)", unique_name(ir)); } void ir_print_visitor::visit(ir_function_signature *ir) { + _mesa_symbol_table_push_scope(symbols); printf("(signature "); indentation++; @@ -148,6 +188,7 @@ void ir_print_visitor::visit(ir_function_signature *ir) indent(); printf("))\n"); indentation--; + _mesa_symbol_table_pop_scope(symbols); } @@ -265,7 +306,7 @@ void ir_print_visitor::visit(ir_swizzle *ir) void ir_print_visitor::visit(ir_dereference_variable *ir) { ir_variable *var = ir->variable_referenced(); - printf("(var_ref %s@%p) ", var->name, (void *) var); + printf("(var_ref %s) ", unique_name(var)); } diff --git a/src/glsl/ir_print_visitor.h b/src/glsl/ir_print_visitor.h index 4feeb8c184d..c7136f11a3b 100644 --- a/src/glsl/ir_print_visitor.h +++ b/src/glsl/ir_print_visitor.h @@ -29,6 +29,10 @@ #include "ir.h" #include "ir_visitor.h" +extern "C" { +#include "program/symbol_table.h" +} + extern void _mesa_print_ir(exec_list *instructions, struct _mesa_glsl_parse_state *state); @@ -37,15 +41,8 @@ extern void _mesa_print_ir(exec_list *instructions, */ class ir_print_visitor : public ir_visitor { public: - ir_print_visitor() - { - indentation = 0; - } - - virtual ~ir_print_visitor() - { - /* empty */ - } + ir_print_visitor(); + virtual ~ir_print_visitor(); void indent(void); @@ -77,6 +74,20 @@ public: /*@}*/ private: + /** + * Fetch/generate a unique name for ir_variable. + * + * GLSL IR permits multiple ir_variables to share the same name. This works + * fine until we try to print it, when we really need a unique one. + */ + const char *unique_name(ir_variable *var); + + /** A mapping from ir_variable * -> unique printable names. */ + hash_table *printable_names; + _mesa_symbol_table *symbols; + + void *mem_ctx; + int indentation; }; |