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