nir: Add a function to detect if a block is immediately followed by an if

Since we don't actually have an "if" instruction, this is a very common
pattern when iterating over instructions.  This adds a helper function for
it to make things a little less painful.

Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
This commit is contained in:
Jason Ekstrand 2014-10-29 16:25:51 -07:00
parent dfdf0c4673
commit d7e482d32c
4 changed files with 30 additions and 13 deletions

View file

@ -1692,6 +1692,23 @@ nir_foreach_block_reverse(nir_function_impl *impl, nir_foreach_block_cb cb,
return true;
}
nir_if *
nir_block_following_if(nir_block *block)
{
if (exec_node_is_tail_sentinel(&block->cf_node.node))
return NULL;
if (nir_cf_node_is_last(&block->cf_node))
return NULL;
nir_cf_node *next_node = nir_cf_node_next(&block->cf_node);
if (next_node->type != nir_cf_node_if)
return NULL;
return nir_cf_node_as_if(next_node);
}
static bool
index_block(nir_block *block, void *state)
{

View file

@ -1277,6 +1277,11 @@ bool nir_foreach_block(nir_function_impl *impl, nir_foreach_block_cb cb,
bool nir_foreach_block_reverse(nir_function_impl *impl, nir_foreach_block_cb cb,
void *state);
/* If the following CF node is an if, this function returns that if.
* Otherwise, it returns NULL.
*/
nir_if *nir_block_following_if(nir_block *block);
void nir_index_local_regs(nir_function_impl *impl);
void nir_index_global_regs(nir_shader *shader);
void nir_index_ssa_defs(nir_function_impl *impl);

View file

@ -107,12 +107,9 @@ convert_from_ssa_block(nir_block *block, void *void_state)
}
}
if (block->cf_node.node.next != NULL && /* check that we aren't the end node */
!nir_cf_node_is_last(&block->cf_node) &&
nir_cf_node_next(&block->cf_node)->type == nir_cf_node_if) {
nir_if *if_stmt = nir_cf_node_as_if(nir_cf_node_next(&block->cf_node));
rewrite_ssa_src(&if_stmt->condition, state);
}
nir_if *following_if = nir_block_following_if(block);
if (following_if)
rewrite_ssa_src(&following_if->condition, state);
return true;
}

View file

@ -123,13 +123,11 @@ init_block_cb(nir_block *block, void *_state)
nir_foreach_instr(block, instr)
init_instr(instr, worklist);
if (block->cf_node.node.next != NULL && /* check that we aren't the end node */
!nir_cf_node_is_last(&block->cf_node) &&
nir_cf_node_next(&block->cf_node)->type == nir_cf_node_if) {
nir_if *if_stmt = nir_cf_node_as_if(nir_cf_node_next(&block->cf_node));
if (if_stmt->condition.is_ssa &&
!if_stmt->condition.ssa->parent_instr->live)
worklist_push(worklist, if_stmt->condition.ssa->parent_instr);
nir_if *following_if = nir_block_following_if(block);
if (following_if) {
if (following_if->condition.is_ssa &&
!following_if->condition.ssa->parent_instr->live)
worklist_push(worklist, following_if->condition.ssa->parent_instr);
}
return true;