[Mesa-dev] [PATCH] glsl: Generate readable unique names at print time.

Kenneth Graunke kenneth at whitecape.org
Fri Mar 25 12:24:09 PDT 2011


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 at 0x6699e3c8 vs. channel_expressions at 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.
---
 src/glsl/ir_print_visitor.cpp |   46 +++++++++++++++++++++++++++++++++++++++-
 src/glsl/ir_print_visitor.h   |   29 +++++++++++++++++--------
 2 files changed, 64 insertions(+), 11 deletions(-)

diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp
index a84f8df..47b4def 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_string_hash, hash_table_string_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,27 @@ 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 +144,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 +189,7 @@ void ir_print_visitor::visit(ir_function_signature *ir)
    indent();
    printf("))\n");
    indentation--;
+   _mesa_symbol_table_pop_scope(symbols);
 }
 
 
@@ -265,7 +307,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 4feeb8c..c7136f1 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;
 };
 
-- 
1.7.4.1



More information about the mesa-dev mailing list