Mesa (master): glsl: Extend the array splitting optimization pass to matrices.

Eric Anholt anholt at kemper.freedesktop.org
Thu Apr 12 01:11:47 UTC 2012


Module: Mesa
Branch: master
Commit: 3bdccbc3e0185fbca16eada2a76f55c6e3f867b5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3bdccbc3e0185fbca16eada2a76f55c6e3f867b5

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Mar 22 13:22:51 2012 -0700

glsl: Extend the array splitting optimization pass to matrices.

This should fit in well with our lower_mat_op_to_vec code: now, in
addition to having expressions on each column of a matrix, we also
split the columns to separate variables so they can be tracked
individually by the copy propagation, dead code, and other passes.

This optimizes out some more code generation in unigine and gstreamer
shaders.

Total instructions: 269342 -> 269270
14/2148 programs affected (0.7%)
2226 -> 2154 instructions in affected programs (3.2% reduction)

---

 src/glsl/opt_array_splitting.cpp |   29 ++++++++++++++++++-----------
 1 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/glsl/opt_array_splitting.cpp b/src/glsl/opt_array_splitting.cpp
index 1e278c1..f11b516 100644
--- a/src/glsl/opt_array_splitting.cpp
+++ b/src/glsl/opt_array_splitting.cpp
@@ -53,9 +53,14 @@ public:
       this->declaration = false;
       this->components = NULL;
       this->mem_ctx = NULL;
+      if (var->type->is_array())
+	 this->size = var->type->length;
+      else
+	 this->size = var->type->matrix_columns;
    }
 
    ir_variable *var; /* The key: the variable's pointer. */
+   unsigned size; /* array length or matrix columns */
 
    /** Number of times the variable is referenced, including assignments. */
    unsigned whole_array_access;
@@ -112,13 +117,13 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var)
        var->mode != ir_var_temporary)
       return NULL;
 
-   if (!var->type->is_array())
+   if (!(var->type->is_array() || var->type->is_matrix()))
       return NULL;
 
    /* If the array hasn't been sized yet, we can't split it.  After
     * linking, this should be resolved.
     */
-   if (var->type->length == 0)
+   if (var->type->is_array() && var->type->length == 0)
       return NULL;
 
    foreach_iter(exec_list_iterator, iter, this->variable_list) {
@@ -239,9 +244,6 @@ ir_array_splitting_visitor::get_splitting_entry(ir_variable *var)
 {
    assert(var);
 
-   if (!var->type->is_array())
-      return NULL;
-
    foreach_iter(exec_list_iterator, iter, *this->variable_list) {
       variable_entry *entry = (variable_entry *)iter.get();
       if (entry->var == var) {
@@ -271,7 +273,7 @@ ir_array_splitting_visitor::split_deref(ir_dereference **deref)
    ir_constant *constant = deref_array->array_index->as_constant();
    assert(constant);
 
-   if (constant->value.i[0] < (int)var->type->length) {
+   if (constant->value.i[0] < (int)entry->size) {
       *deref = new(entry->mem_ctx)
 	 ir_dereference_variable(entry->components[constant->value.i[0]]);
    } else {
@@ -343,21 +345,26 @@ optimize_split_arrays(exec_list *instructions, bool linked)
    foreach_iter(exec_list_iterator, iter, refs.variable_list) {
       variable_entry *entry = (variable_entry *)iter.get();
       const struct glsl_type *type = entry->var->type;
+      const struct glsl_type *subtype;
+
+      if (type->is_matrix())
+	 subtype = glsl_type::get_instance(GLSL_TYPE_FLOAT,
+					   type->vector_elements, 1);
+      else
+	 subtype = type->fields.array;
 
       entry->mem_ctx = ralloc_parent(entry->var);
 
       entry->components = ralloc_array(mem_ctx,
 				       ir_variable *,
-				       type->length);
+				       entry->size);
 
-      for (unsigned int i = 0; i < type->length; i++) {
+      for (unsigned int i = 0; i < entry->size; i++) {
 	 const char *name = ralloc_asprintf(mem_ctx, "%s_%d",
 					    entry->var->name, i);
 
 	 entry->components[i] =
-	    new(entry->mem_ctx) ir_variable(type->fields.array,
-					    name,
-					    ir_var_temporary);
+	    new(entry->mem_ctx) ir_variable(subtype, name, ir_var_temporary);
 	 entry->var->insert_before(entry->components[i]);
       }
 




More information about the mesa-commit mailing list