nir: Add a new helper for iterating phi sources leaving a block

This takes the same callback as nir_foreach_src except it walks all phi
sources which leave a given block.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5094>
This commit is contained in:
Jason Ekstrand 2020-05-18 16:49:29 -05:00 committed by Marge Bot
parent 2c8c5cc87d
commit 3fdbeb70e1
3 changed files with 30 additions and 15 deletions

View file

@ -1256,6 +1256,32 @@ nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state)
return nir_foreach_dest(instr, visit_dest_indirect, &dest_state);
}
bool
nir_foreach_phi_src_leaving_block(nir_block *block,
nir_foreach_src_cb cb,
void *state)
{
for (unsigned i = 0; i < ARRAY_SIZE(block->successors); i++) {
if (block->successors[i] == NULL)
continue;
nir_foreach_instr(instr, block->successors[i]) {
if (instr->type != nir_instr_type_phi)
break;
nir_phi_instr *phi = nir_instr_as_phi(instr);
nir_foreach_phi_src(phi_src, phi) {
if (phi_src->pred == block) {
if (!cb(&phi_src->src, state))
return false;
}
}
}
}
return true;
}
nir_const_value
nir_const_value_for_float(double f, unsigned bit_size)
{

View file

@ -3554,6 +3554,9 @@ bool nir_foreach_ssa_def(nir_instr *instr, nir_foreach_ssa_def_cb cb,
void *state);
bool nir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state);
bool nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state);
bool nir_foreach_phi_src_leaving_block(nir_block *instr,
nir_foreach_src_cb cb,
void *state);
nir_const_value *nir_src_as_const_value(nir_src src);

View file

@ -273,21 +273,7 @@ nir_lower_regs_to_ssa_impl(nir_function_impl *impl)
* loops, a phi source may be a back-edge so we have to handle it as if
* it were one of the last instructions in the predecessor block.
*/
for (unsigned i = 0; i < ARRAY_SIZE(block->successors); i++) {
if (block->successors[i] == NULL)
continue;
nir_foreach_instr(instr, block->successors[i]) {
if (instr->type != nir_instr_type_phi)
break;
nir_phi_instr *phi = nir_instr_as_phi(instr);
nir_foreach_phi_src(phi_src, phi) {
if (phi_src->pred == block)
rewrite_src(&phi_src->src, &state);
}
}
}
nir_foreach_phi_src_leaving_block(block, rewrite_src, &state);
}
nir_phi_builder_finish(phi_build);