nir/loop_analyze: Use nir_loop_variable::init_src instead of nir_basic_induction_var::def_outside_loop
These track the same information in a slightly different way. Since nir_loop_variable::init_src is visible outside this module, it cannot be eliminated. As an intentional side effect, induction variables with constant initializers will now have their nir_loop_induction_variable::init_src field point to the load_const source. Previously this pointer would be NULL. v2: Update unit tests and commit message. Remove the now unused ind_var variable in find_trip_count. Reviewed-by: Caio Oliveira <caio.oliveira@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21289>
This commit is contained in:
@@ -423,7 +423,6 @@ compute_induction_information(loop_info_state *state)
|
|||||||
nir_phi_instr *phi = nir_instr_as_phi(var->def->parent_instr);
|
nir_phi_instr *phi = nir_instr_as_phi(var->def->parent_instr);
|
||||||
nir_basic_induction_var *biv = rzalloc(state, nir_basic_induction_var);
|
nir_basic_induction_var *biv = rzalloc(state, nir_basic_induction_var);
|
||||||
|
|
||||||
nir_src *init_src = NULL;
|
|
||||||
nir_loop_variable *alu_src_var = NULL;
|
nir_loop_variable *alu_src_var = NULL;
|
||||||
nir_foreach_phi_src(src, phi) {
|
nir_foreach_phi_src(src, phi) {
|
||||||
nir_loop_variable *src_var = get_loop_var(src->src.ssa, state);
|
nir_loop_variable *src_var = get_loop_var(src->src.ssa, state);
|
||||||
@@ -448,9 +447,8 @@ compute_induction_information(loop_info_state *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!src_var->in_loop && !biv->def_outside_loop) {
|
if (!src_var->in_loop && !var->init_src) {
|
||||||
biv->def_outside_loop = src_var->def;
|
var->init_src = &src->src;
|
||||||
init_src = &src->src;
|
|
||||||
} else if (is_var_alu(src_var) && !var->update_src) {
|
} else if (is_var_alu(src_var) && !var->update_src) {
|
||||||
alu_src_var = src_var;
|
alu_src_var = src_var;
|
||||||
nir_alu_instr *alu = nir_instr_as_alu(src_var->def->parent_instr);
|
nir_alu_instr *alu = nir_instr_as_alu(src_var->def->parent_instr);
|
||||||
@@ -480,8 +478,8 @@ compute_induction_information(loop_info_state *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var->update_src && biv->def_outside_loop) {
|
if (var->update_src && var->init_src) {
|
||||||
nir_instr *inst = biv->def_outside_loop->parent_instr;
|
nir_instr *inst = var->init_src->ssa->parent_instr;
|
||||||
if (inst->type == nir_instr_type_load_const) {
|
if (inst->type == nir_instr_type_load_const) {
|
||||||
/* Initial value of induction variable is a constant */
|
/* Initial value of induction variable is a constant */
|
||||||
alu_src_var->init_src = var->init_src;
|
alu_src_var->init_src = var->init_src;
|
||||||
@@ -493,20 +491,20 @@ compute_induction_information(loop_info_state *state)
|
|||||||
|
|
||||||
found_induction_var = true;
|
found_induction_var = true;
|
||||||
num_induction_vars += 2;
|
num_induction_vars += 2;
|
||||||
} else if (is_only_uniform_src(init_src)) {
|
} else if (is_only_uniform_src(var->init_src)) {
|
||||||
/* Initial value of induction variable is a uniform */
|
/* Initial value of induction variable is a uniform */
|
||||||
var->init_src = init_src;
|
|
||||||
|
|
||||||
alu_src_var->init_src = var->init_src;
|
alu_src_var->init_src = var->init_src;
|
||||||
alu_src_var->update_src = var->update_src;
|
alu_src_var->update_src = var->update_src;
|
||||||
|
|
||||||
num_induction_vars += 2;
|
num_induction_vars += 2;
|
||||||
ralloc_free(biv);
|
ralloc_free(biv);
|
||||||
} else {
|
} else {
|
||||||
|
var->init_src = NULL;
|
||||||
var->update_src = NULL;
|
var->update_src = NULL;
|
||||||
ralloc_free(biv);
|
ralloc_free(biv);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
var->init_src = NULL;
|
||||||
var->update_src = NULL;
|
var->update_src = NULL;
|
||||||
ralloc_free(biv);
|
ralloc_free(biv);
|
||||||
}
|
}
|
||||||
@@ -1195,13 +1193,12 @@ find_trip_count(loop_info_state *state, unsigned execution_mode)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
nir_loop_variable *lv = get_loop_var(basic_ind.def, state);
|
nir_loop_variable *lv = get_loop_var(basic_ind.def, state);
|
||||||
nir_basic_induction_var *ind_var = lv->ind;
|
|
||||||
|
|
||||||
/* The basic induction var might be a vector but, because we guarantee
|
/* The basic induction var might be a vector but, because we guarantee
|
||||||
* earlier that the phi source has a scalar swizzle, we can take the
|
* earlier that the phi source has a scalar swizzle, we can take the
|
||||||
* component from basic_ind.
|
* component from basic_ind.
|
||||||
*/
|
*/
|
||||||
nir_ssa_scalar initial_s = { ind_var->def_outside_loop, basic_ind.comp };
|
nir_ssa_scalar initial_s = { lv->init_src->ssa, basic_ind.comp };
|
||||||
nir_ssa_scalar alu_s = {
|
nir_ssa_scalar alu_s = {
|
||||||
lv->update_src->src.ssa,
|
lv->update_src->src.ssa,
|
||||||
lv->update_src->swizzle[basic_ind.comp]
|
lv->update_src->swizzle[basic_ind.comp]
|
||||||
|
@@ -248,15 +248,15 @@ TEST_F(nir_loop_analyze_test, infinite_loop_feq)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
@@ -330,15 +330,15 @@ TEST_F(nir_loop_analyze_test, zero_iterations_ine)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
@@ -409,15 +409,15 @@ TEST_F(nir_loop_analyze_test, one_iteration_uge)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
@@ -488,15 +488,15 @@ TEST_F(nir_loop_analyze_test, one_iteration_ine)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
@@ -567,15 +567,15 @@ TEST_F(nir_loop_analyze_test, one_iteration_ieq)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
@@ -646,15 +646,15 @@ TEST_F(nir_loop_analyze_test, one_iteration_easy_fneu)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
@@ -730,15 +730,15 @@ TEST_F(nir_loop_analyze_test, one_iteration_fneu)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
@@ -811,15 +811,15 @@ TEST_F(nir_loop_analyze_test, zero_iterations_ine_inverted)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
@@ -892,15 +892,15 @@ TEST_F(nir_loop_analyze_test, five_iterations_ige_inverted)
|
|||||||
EXPECT_EQ(2, loop->info->num_induction_vars);
|
EXPECT_EQ(2, loop->info->num_induction_vars);
|
||||||
ASSERT_NE((void *)0, loop->info->induction_vars);
|
ASSERT_NE((void *)0, loop->info->induction_vars);
|
||||||
|
|
||||||
/* Since the initializer is a constant, the init_src field will be
|
/* The def field should not be NULL. The init_src field should point to a
|
||||||
* NULL. The def field should not be NULL. The update_src field should
|
* load_const. The update_src field should point to a load_const.
|
||||||
* point to a load_const.
|
|
||||||
*/
|
*/
|
||||||
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
const nir_loop_induction_variable *const ivars = loop->info->induction_vars;
|
||||||
|
|
||||||
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
for (unsigned i = 0; i < loop->info->num_induction_vars; i++) {
|
||||||
EXPECT_NE((void *)0, ivars[i].def);
|
EXPECT_NE((void *)0, ivars[i].def);
|
||||||
EXPECT_EQ((void *)0, ivars[i].init_src);
|
ASSERT_NE((void *)0, ivars[i].init_src);
|
||||||
|
EXPECT_TRUE(nir_src_is_const(*ivars[i].init_src));
|
||||||
ASSERT_NE((void *)0, ivars[i].update_src);
|
ASSERT_NE((void *)0, ivars[i].update_src);
|
||||||
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
EXPECT_TRUE(nir_src_is_const(ivars[i].update_src->src));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user