Mesa (glsl2): glsl2: Handle plain variable copies in struct splitting.

Eric Anholt anholt at kemper.freedesktop.org
Mon Aug 9 06:46:48 UTC 2010


Module: Mesa
Branch: glsl2
Commit: f8d2cfe4a699faebd42bd1874ef0329d37791dd7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f8d2cfe4a699faebd42bd1874ef0329d37791dd7

Author: Eric Anholt <eric at anholt.net>
Date:   Sun Aug  8 23:29:54 2010 -0700

glsl2: Handle plain variable copies in struct splitting.

glsl-fs-raytrace goes from 620 Mesa IR instructions out of the
compiler to 585.

---

 src/glsl/ir_structure_splitting.cpp |   54 +++++++++++++++++++++++++++++++++--
 1 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/src/glsl/ir_structure_splitting.cpp b/src/glsl/ir_structure_splitting.cpp
index 902eead..f993167 100644
--- a/src/glsl/ir_structure_splitting.cpp
+++ b/src/glsl/ir_structure_splitting.cpp
@@ -80,7 +80,7 @@ public:
    virtual ir_visitor_status visit(ir_variable *);
    virtual ir_visitor_status visit(ir_dereference_variable *);
    virtual ir_visitor_status visit_enter(ir_dereference_record *);
-
+   virtual ir_visitor_status visit_enter(ir_assignment *);
    virtual ir_visitor_status visit_enter(ir_function_signature *);
 
    variable_entry *get_variable_entry(ir_variable *var);
@@ -142,6 +142,19 @@ ir_structure_reference_visitor::visit_enter(ir_dereference_record *ir)
 }
 
 ir_visitor_status
+ir_structure_reference_visitor::visit_enter(ir_assignment *ir)
+{
+   if (ir->lhs->as_dereference_variable() &&
+       ir->rhs->as_dereference_variable() &&
+       !ir->condition) {
+      /* We'll split copies of a structure to copies of components, so don't
+       * descend to the ir_dereference_variables.
+       */
+      return visit_continue_with_parent;
+   }
+}
+
+ir_visitor_status
 ir_structure_reference_visitor::visit_enter(ir_function_signature *ir)
 {
    /* We don't want to descend into the function parameters and
@@ -302,9 +315,44 @@ ir_structure_splitting_visitor::visit_leave(ir_dereference_record *ir)
 ir_visitor_status
 ir_structure_splitting_visitor::visit_leave(ir_assignment *ir)
 {
-   split_rvalue(&ir->rhs);
+   ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable();
+   ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable();
+   variable_entry *lhs_entry = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL;
+   variable_entry *rhs_entry = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL;
+   const glsl_type *type = ir->rhs->type;
+
+   if ((lhs_entry || rhs_entry) && !ir->condition) {
+      for (unsigned int i = 0; i < type->length; i++) {
+	 ir_dereference *new_lhs, *new_rhs;
+	 void *mem_ctx = lhs_entry ? lhs_entry->mem_ctx : rhs_entry->mem_ctx;
+
+	 if (lhs_entry) {
+	    new_lhs = new(mem_ctx) ir_dereference_variable(lhs_entry->components[i]);
+	 } else {
+	    new_lhs = new(mem_ctx)
+	       ir_dereference_record(ir->lhs->clone(mem_ctx, NULL),
+				     type->fields.structure[i].name);
+	 }
+
+	 if (rhs_entry) {
+	    new_rhs = new(mem_ctx) ir_dereference_variable(rhs_entry->components[i]);
+	 } else {
+	    new_rhs = new(mem_ctx)
+	       ir_dereference_record(ir->rhs->clone(mem_ctx, NULL),
+				     type->fields.structure[i].name);
+	 }
+
+	 ir->insert_before(new(mem_ctx) ir_assignment(new_lhs,
+						      new_rhs,
+						      NULL));
+      }
+      ir->remove();
+   } else {
+      split_rvalue(&ir->rhs);
+      split_deref(&ir->lhs);
+   }
+
    split_rvalue(&ir->condition);
-   split_deref(&ir->lhs);
 
    return visit_continue;
 }




More information about the mesa-commit mailing list