summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/opt_array_splitting.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/glsl/opt_array_splitting.cpp')
-rw-r--r--src/compiler/glsl/opt_array_splitting.cpp68
1 files changed, 38 insertions, 30 deletions
diff --git a/src/compiler/glsl/opt_array_splitting.cpp b/src/compiler/glsl/opt_array_splitting.cpp
index cceec6b6431..a294da56616 100644
--- a/src/compiler/glsl/opt_array_splitting.cpp
+++ b/src/compiler/glsl/opt_array_splitting.cpp
@@ -55,9 +55,9 @@ public:
this->components = NULL;
this->mem_ctx = NULL;
if (var->type->is_array())
- this->size = var->type->length;
+ this->size = var->type->length;
else
- this->size = var->type->matrix_columns;
+ this->size = var->type->matrix_columns;
}
ir_variable *var; /* The key: the variable's pointer. */
@@ -137,7 +137,7 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var)
foreach_in_list(variable_entry, entry, &this->variable_list) {
if (entry->var == var)
- return entry;
+ return entry;
}
variable_entry *entry = new(mem_ctx) variable_entry(var);
@@ -185,8 +185,18 @@ ir_array_reference_visitor::visit_enter(ir_dereference_array *ir)
/* If the access to the array has a variable index, we wouldn't
* know which split variable this dereference should go to.
*/
- if (entry && !ir->array_index->as_constant())
- entry->split = false;
+ if (!ir->array_index->as_constant()) {
+ if (entry)
+ entry->split = false;
+ /* This variable indexing could come from a different array dereference
+ * that also has variable indexing, that is, something like a[b[a[b[0]]]].
+ * If we return visit_continue_with_parent here for the first appearence
+ * of a, then we can miss that b also has indirect indexing (if this is
+ * the only place in the program where such indirect indexing into b
+ * happens), so keep going.
+ */
+ return visit_continue;
+ }
/* If the index is also array dereference, visit index. */
if (ir->array_index->as_dereference_array())
@@ -208,7 +218,7 @@ ir_array_reference_visitor::visit_enter(ir_function_signature *ir)
bool
ir_array_reference_visitor::get_split_list(exec_list *instructions,
- bool linked)
+ bool linked)
{
visit_list_elements(this, instructions);
@@ -217,25 +227,25 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions,
*/
if (!linked) {
foreach_in_list(ir_instruction, node, instructions) {
- ir_variable *var = node->as_variable();
- if (var) {
- variable_entry *entry = get_variable_entry(var);
- if (entry)
- entry->remove();
- }
+ ir_variable *var = node->as_variable();
+ if (var) {
+ variable_entry *entry = get_variable_entry(var);
+ if (entry)
+ entry->remove();
+ }
}
}
/* Trim out variables we found that we can't split. */
foreach_in_list_safe(variable_entry, entry, &variable_list) {
if (debug) {
- printf("array %s@%p: decl %d, split %d\n",
- entry->var->name, (void *) entry->var, entry->declaration,
- entry->split);
+ printf("array %s@%p: decl %d, split %d\n",
+ entry->var->name, (void *) entry->var, entry->declaration,
+ entry->split);
}
if (!(entry->declaration && entry->split)) {
- entry->remove();
+ entry->remove();
}
}
@@ -273,7 +283,7 @@ ir_array_splitting_visitor::get_splitting_entry(ir_variable *var)
foreach_in_list(variable_entry, entry, this->variable_list) {
if (entry->var == var) {
- return entry;
+ return entry;
}
}
@@ -301,7 +311,7 @@ ir_array_splitting_visitor::split_deref(ir_dereference **deref)
if (constant->value.i[0] >= 0 && constant->value.i[0] < (int)entry->size) {
*deref = new(entry->mem_ctx)
- ir_dereference_variable(entry->components[constant->value.i[0]]);
+ ir_dereference_variable(entry->components[constant->value.i[0]]);
} else {
/* There was a constant array access beyond the end of the
* array. This might have happened due to constant folding
@@ -310,8 +320,8 @@ ir_array_splitting_visitor::split_deref(ir_dereference **deref)
* variable.
*/
ir_variable *temp = new(entry->mem_ctx) ir_variable(deref_array->type,
- "undef",
- ir_var_temporary);
+ "undef",
+ ir_var_temporary);
entry->components[0]->insert_before(temp);
*deref = new(entry->mem_ctx) ir_dereference_variable(temp);
}
@@ -373,23 +383,21 @@ optimize_split_arrays(exec_list *instructions, bool linked)
const struct glsl_type *subtype;
if (type->is_matrix())
- subtype = type->column_type();
+ subtype = type->column_type();
else
- subtype = type->fields.array;
+ subtype = type->fields.array;
entry->mem_ctx = ralloc_parent(entry->var);
- entry->components = ralloc_array(mem_ctx,
- ir_variable *,
- entry->size);
+ entry->components = ralloc_array(mem_ctx, ir_variable *, entry->size);
for (unsigned int i = 0; i < entry->size; i++) {
- const char *name = ralloc_asprintf(mem_ctx, "%s_%d",
- entry->var->name, i);
+ const char *name = ralloc_asprintf(mem_ctx, "%s_%d",
+ entry->var->name, i);
- entry->components[i] =
- new(entry->mem_ctx) ir_variable(subtype, name, ir_var_temporary);
- entry->var->insert_before(entry->components[i]);
+ entry->components[i] =
+ new(entry->mem_ctx) ir_variable(subtype, name, ir_var_temporary);
+ entry->var->insert_before(entry->components[i]);
}
entry->var->remove();