nir: rework force_unroll_array_access()

Here we rework force_unroll_array_access() so that we can reuse
the induction variable detection in a following patch.

Reviewed-by: Thomas Helland <thomashelland90@gmail.com>
This commit is contained in:
Timothy Arceri
2018-11-15 21:28:31 +11:00
parent 48135f175c
commit 721566bddb

View File

@@ -350,6 +350,38 @@ find_loop_terminators(loop_info_state *state)
return success;
}
/* This function looks for an array access within a loop that uses an
* induction variable for the array index. If found it returns the size of the
* array, otherwise 0 is returned. If we find an induction var we pass it back
* to the caller via array_index_out.
*/
static unsigned
find_array_access_via_induction(loop_info_state *state,
nir_deref_instr *deref,
nir_loop_variable **array_index_out)
{
for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) {
if (d->deref_type != nir_deref_type_array)
continue;
assert(d->arr.index.is_ssa);
nir_loop_variable *array_index = get_loop_var(d->arr.index.ssa, state);
if (array_index->type != basic_induction)
continue;
if (array_index_out)
*array_index_out = array_index;
nir_deref_instr *parent = nir_deref_instr_parent(d);
assert(glsl_type_is_array_or_matrix(parent->type));
return glsl_get_length(parent->type);
}
return 0;
}
static int32_t
get_iteration(nir_op cond_op, nir_const_value *initial, nir_const_value *step,
nir_const_value *limit)
@@ -626,20 +658,9 @@ find_trip_count(loop_info_state *state)
static bool
force_unroll_array_access(loop_info_state *state, nir_deref_instr *deref)
{
for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) {
if (d->deref_type != nir_deref_type_array)
continue;
assert(d->arr.index.is_ssa);
nir_loop_variable *array_index = get_loop_var(d->arr.index.ssa, state);
if (array_index->type != basic_induction)
continue;
nir_deref_instr *parent = nir_deref_instr_parent(d);
assert(glsl_type_is_array(parent->type) ||
glsl_type_is_matrix(parent->type));
if (glsl_get_length(parent->type) == state->loop->info->max_trip_count)
unsigned array_size = find_array_access_via_induction(state, deref, NULL);
if (array_size) {
if (array_size == state->loop->info->max_trip_count)
return true;
if (deref->mode & state->indirect_mask)