...
 
Commits (5)
...@@ -60,7 +60,7 @@ typedef struct { ...@@ -60,7 +60,7 @@ typedef struct {
typedef struct nir_basic_induction_var { typedef struct nir_basic_induction_var {
nir_op alu_op; /* The type of alu-operation */ nir_op alu_op; /* The type of alu-operation */
nir_loop_variable *alu_def; /* The def of the alu-operation */ nir_loop_variable *alu_def; /* The def of the alu-operation */
nir_loop_variable *invariant; /* The invariant alu-operand */ nir_alu_src *invariant; /* The invariant alu-src */
nir_loop_variable *def_outside_loop; /* The phi-src outside the loop */ nir_loop_variable *def_outside_loop; /* The phi-src outside the loop */
} nir_basic_induction_var; } nir_basic_induction_var;
...@@ -356,7 +356,7 @@ compute_induction_information(loop_info_state *state) ...@@ -356,7 +356,7 @@ compute_induction_information(loop_info_state *state)
/* Is one of the operands const, and the other the phi */ /* Is one of the operands const, and the other the phi */
if (alu->src[i].src.ssa->parent_instr->type == nir_instr_type_load_const && if (alu->src[i].src.ssa->parent_instr->type == nir_instr_type_load_const &&
alu->src[1-i].src.ssa == &phi->dest.ssa) alu->src[1-i].src.ssa == &phi->dest.ssa)
biv->invariant = get_loop_var(alu->src[i].src.ssa, state); biv->invariant = &alu->src[i];
} }
} }
} }
...@@ -364,7 +364,7 @@ compute_induction_information(loop_info_state *state) ...@@ -364,7 +364,7 @@ compute_induction_information(loop_info_state *state)
if (biv->alu_def && biv->def_outside_loop && biv->invariant && if (biv->alu_def && biv->def_outside_loop && biv->invariant &&
is_var_constant(biv->def_outside_loop)) { is_var_constant(biv->def_outside_loop)) {
assert(is_var_constant(biv->invariant)); assert(is_var_constant(get_loop_var(biv->invariant->src.ssa, state)));
biv->alu_def->type = basic_induction; biv->alu_def->type = basic_induction;
biv->alu_def->ind = biv; biv->alu_def->ind = biv;
var->type = basic_induction; var->type = basic_induction;
...@@ -543,25 +543,28 @@ guess_loop_limit(loop_info_state *state, nir_const_value *limit_val, ...@@ -543,25 +543,28 @@ guess_loop_limit(loop_info_state *state, nir_const_value *limit_val,
} }
static bool static bool
try_find_limit_of_alu(nir_loop_variable *limit, nir_const_value *limit_val, try_find_limit_of_alu(nir_alu_src *limit, nir_const_value *limit_val,
nir_loop_terminator *terminator, loop_info_state *state) nir_loop_terminator *terminator)
{ {
if(!is_var_alu(limit)) if(limit->src.ssa->parent_instr->type != nir_instr_type_alu)
return false; return false;
nir_alu_instr *limit_alu = nir_instr_as_alu(limit->def->parent_instr); nir_alu_instr *limit_alu = nir_instr_as_alu(limit->src.ssa->parent_instr);
if (limit_alu->op == nir_op_imin || if (limit_alu->op == nir_op_imin ||
limit_alu->op == nir_op_fmin) { limit_alu->op == nir_op_fmin) {
limit = get_loop_var(limit_alu->src[0].src.ssa, state); limit = &limit_alu->src[0];
if (!is_var_constant(limit)) if (limit->src.ssa->parent_instr->type != nir_instr_type_load_const)
limit = get_loop_var(limit_alu->src[1].src.ssa, state); limit = &limit_alu->src[1];
if (!is_var_constant(limit)) if (limit->src.ssa->parent_instr->type != nir_instr_type_load_const)
return false; return false;
*limit_val = nir_instr_as_load_const(limit->def->parent_instr)->value[0]; unsigned limit_swz = limit->swizzle[0];
*limit_val =
nir_instr_as_load_const(limit->src.ssa->parent_instr)
->value[limit_swz];
terminator->exact_trip_count_unknown = true; terminator->exact_trip_count_unknown = true;
...@@ -777,19 +780,19 @@ is_supported_terminator_condition(nir_alu_instr *alu) ...@@ -777,19 +780,19 @@ is_supported_terminator_condition(nir_alu_instr *alu)
static bool static bool
get_induction_and_limit_vars(nir_alu_instr *alu, nir_loop_variable **ind, get_induction_and_limit_vars(nir_alu_instr *alu, nir_loop_variable **ind,
nir_loop_variable **limit, nir_alu_src **limit,
loop_info_state *state) loop_info_state *state)
{ {
bool limit_rhs = true; bool limit_rhs = true;
/* We assume that the limit is the "right" operand */ /* We assume that the limit is the "right" operand */
*ind = get_loop_var(alu->src[0].src.ssa, state); *ind = get_loop_var(alu->src[0].src.ssa, state);
*limit = get_loop_var(alu->src[1].src.ssa, state); *limit = &alu->src[1];
if ((*ind)->type != basic_induction) { if ((*ind)->type != basic_induction) {
/* We had it the wrong way, flip things around */ /* We had it the wrong way, flip things around */
*ind = get_loop_var(alu->src[1].src.ssa, state); *ind = get_loop_var(alu->src[1].src.ssa, state);
*limit = get_loop_var(alu->src[0].src.ssa, state); *limit = &alu->src[0];
limit_rhs = false; limit_rhs = false;
} }
...@@ -799,7 +802,7 @@ get_induction_and_limit_vars(nir_alu_instr *alu, nir_loop_variable **ind, ...@@ -799,7 +802,7 @@ get_induction_and_limit_vars(nir_alu_instr *alu, nir_loop_variable **ind,
static void static void
try_find_trip_count_vars_in_iand(nir_alu_instr **alu, try_find_trip_count_vars_in_iand(nir_alu_instr **alu,
nir_loop_variable **ind, nir_loop_variable **ind,
nir_loop_variable **limit, nir_alu_src **limit,
bool *limit_rhs, bool *limit_rhs,
loop_info_state *state) loop_info_state *state)
{ {
...@@ -848,7 +851,7 @@ try_find_trip_count_vars_in_iand(nir_alu_instr **alu, ...@@ -848,7 +851,7 @@ try_find_trip_count_vars_in_iand(nir_alu_instr **alu,
/* Try the other iand src if needed */ /* Try the other iand src if needed */
if (*ind == NULL || (*ind && (*ind)->type != basic_induction) || if (*ind == NULL || (*ind && (*ind)->type != basic_induction) ||
!is_var_constant(*limit)) { (*limit)->src.ssa->parent_instr->type != nir_instr_type_load_const) {
src = iand->src[1].src.ssa; src = iand->src[1].src.ssa;
if (src->parent_instr->type == nir_instr_type_alu) { if (src->parent_instr->type == nir_instr_type_alu) {
nir_alu_instr *tmp_alu = nir_instr_as_alu(src->parent_instr); nir_alu_instr *tmp_alu = nir_instr_as_alu(src->parent_instr);
...@@ -889,9 +892,9 @@ find_trip_count(loop_info_state *state) ...@@ -889,9 +892,9 @@ find_trip_count(loop_info_state *state)
nir_alu_instr *alu = nir_instr_as_alu(terminator->conditional_instr); nir_alu_instr *alu = nir_instr_as_alu(terminator->conditional_instr);
nir_op alu_op = alu->op; nir_op alu_op = alu->op;
bool limit_rhs; bool limit_rhs = false;
nir_loop_variable *basic_ind = NULL; nir_loop_variable *basic_ind = NULL;
nir_loop_variable *limit; nir_alu_src *limit;
if (alu->op == nir_op_inot || alu->op == nir_op_ieq) { if (alu->op == nir_op_inot || alu->op == nir_op_ieq) {
nir_alu_instr *new_alu = alu; nir_alu_instr *new_alu = alu;
try_find_trip_count_vars_in_iand(&new_alu, &basic_ind, &limit, try_find_trip_count_vars_in_iand(&new_alu, &basic_ind, &limit,
...@@ -931,13 +934,15 @@ find_trip_count(loop_info_state *state) ...@@ -931,13 +934,15 @@ find_trip_count(loop_info_state *state)
/* Attempt to find a constant limit for the loop */ /* Attempt to find a constant limit for the loop */
nir_const_value limit_val; nir_const_value limit_val;
if (is_var_constant(limit)) { if (limit->src.ssa->parent_instr->type == nir_instr_type_load_const) {
unsigned limit_swz = limit->swizzle[0];
limit_val = limit_val =
nir_instr_as_load_const(limit->def->parent_instr)->value[0]; nir_instr_as_load_const(limit->src.ssa->parent_instr)
->value[limit_swz];
} else { } else {
trip_count_known = false; trip_count_known = false;
if (!try_find_limit_of_alu(limit, &limit_val, terminator, state)) { if (!try_find_limit_of_alu(limit, &limit_val, terminator)) {
/* Guess loop limit based on array access */ /* Guess loop limit based on array access */
if (!guess_loop_limit(state, &limit_val, basic_ind)) { if (!guess_loop_limit(state, &limit_val, basic_ind)) {
continue; continue;
...@@ -959,9 +964,10 @@ find_trip_count(loop_info_state *state) ...@@ -959,9 +964,10 @@ find_trip_count(loop_info_state *state)
nir_instr_as_load_const(basic_ind->ind->def_outside_loop-> nir_instr_as_load_const(basic_ind->ind->def_outside_loop->
def->parent_instr)->value; def->parent_instr)->value;
unsigned invariant_swz = basic_ind->ind->invariant->swizzle[0];
nir_const_value *step_val = nir_const_value *step_val =
nir_instr_as_load_const(basic_ind->ind->invariant->def-> &(nir_instr_as_load_const(basic_ind->ind->invariant->src.ssa->
parent_instr)->value; parent_instr)->value[invariant_swz]);
int iterations = calculate_iterations(initial_val, step_val, int iterations = calculate_iterations(initial_val, step_val,
&limit_val, &limit_val,
......