glsl: Mark a set of array elements as accessed using a list of array_deref_range

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Ian Romanick
2016-12-15 14:01:28 -08:00
parent 8d499f60c8
commit e92935089b
3 changed files with 253 additions and 0 deletions
+55
View File
@@ -60,6 +60,14 @@ ir_array_refcount_entry::ir_array_refcount_entry(ir_variable *var)
num_bits = MAX2(1, var->type->arrays_of_arrays_size());
bits = new BITSET_WORD[BITSET_WORDS(num_bits)];
memset(bits, 0, BITSET_WORDS(num_bits) * sizeof(bits[0]));
/* Count the "depth" of the arrays-of-arrays. */
array_depth = 0;
for (const glsl_type *type = var->type;
type->is_array();
type = type->fields.array) {
array_depth++;
}
}
@@ -69,6 +77,53 @@ ir_array_refcount_entry::~ir_array_refcount_entry()
}
void
ir_array_refcount_entry::mark_array_elements_referenced(const array_deref_range *dr,
unsigned count)
{
if (count != array_depth)
return;
mark_array_elements_referenced(dr, count, 1, 0);
}
void
ir_array_refcount_entry::mark_array_elements_referenced(const array_deref_range *dr,
unsigned count,
unsigned scale,
unsigned linearized_index)
{
/* Walk through the list of array dereferences in least- to
* most-significant order. Along the way, accumulate the current
* linearized offset and the scale factor for each array-of-.
*/
for (unsigned i = 0; i < count; i++) {
if (dr[i].index < dr[i].size) {
linearized_index += dr[i].index * scale;
scale *= dr[i].size;
} else {
/* For each element in the current array, update the count and
* offset, then recurse to process the remaining arrays.
*
* There is some inefficency here if the last element in the
* array_deref_range list specifies the entire array. In that case,
* the loop will make recursive calls with count == 0. In the call,
* all that will happen is the bit will be set.
*/
for (unsigned j = 0; j < dr[i].size; j++) {
mark_array_elements_referenced(&dr[i + 1],
count - (i + 1),
scale * dr[i].size,
linearized_index + (j * scale));
}
return;
}
}
BITSET_SET(bits, linearized_index);
}
ir_array_refcount_entry *
ir_array_refcount_visitor::get_variable_entry(ir_variable *var)
{