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>
This commit is contained in:
Kenneth Graunke
2011-03-25 10:59:46 -07:00
parent eb0dd37094
commit 56ef62d988
2 changed files with 63 additions and 11 deletions

View File

@@ -25,6 +25,10 @@
#include "glsl_types.h" #include "glsl_types.h"
#include "glsl_parser_extras.h" #include "glsl_parser_extras.h"
extern "C" {
#include "program/hash_table.h"
}
static void print_type(const glsl_type *t); static void print_type(const glsl_type *t);
void void
@@ -67,6 +71,21 @@ _mesa_print_ir(exec_list *instructions,
printf("\n)"); 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) void ir_print_visitor::indent(void)
{ {
@@ -74,6 +93,26 @@ void ir_print_visitor::indent(void)
printf(" "); 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 static void
print_type(const glsl_type *t) 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]); cent, inv, mode[ir->mode], interp[ir->interpolation]);
print_type(ir->type); 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) void ir_print_visitor::visit(ir_function_signature *ir)
{ {
_mesa_symbol_table_push_scope(symbols);
printf("(signature "); printf("(signature ");
indentation++; indentation++;
@@ -148,6 +188,7 @@ void ir_print_visitor::visit(ir_function_signature *ir)
indent(); indent();
printf("))\n"); printf("))\n");
indentation--; 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) void ir_print_visitor::visit(ir_dereference_variable *ir)
{ {
ir_variable *var = ir->variable_referenced(); ir_variable *var = ir->variable_referenced();
printf("(var_ref %s@%p) ", var->name, (void *) var); printf("(var_ref %s) ", unique_name(var));
} }

View File

@@ -29,6 +29,10 @@
#include "ir.h" #include "ir.h"
#include "ir_visitor.h" #include "ir_visitor.h"
extern "C" {
#include "program/symbol_table.h"
}
extern void _mesa_print_ir(exec_list *instructions, extern void _mesa_print_ir(exec_list *instructions,
struct _mesa_glsl_parse_state *state); 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 { class ir_print_visitor : public ir_visitor {
public: public:
ir_print_visitor() ir_print_visitor();
{ virtual ~ir_print_visitor();
indentation = 0;
}
virtual ~ir_print_visitor()
{
/* empty */
}
void indent(void); void indent(void);
@@ -77,6 +74,20 @@ public:
/*@}*/ /*@}*/
private: 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; int indentation;
}; };