nir: Properly clean up CF nodes when we remove them
Previously, if you remved a CF node that still had instructions in it, none of the use/def information from those instructions would get cleaned up. Also, we weren't removing if statements from the if_uses of the corresponding register or SSA def. This commit fixes both of these problems Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
This commit is contained in:
parent
e025943134
commit
98ecb25f89
|
@ -1150,6 +1150,58 @@ stitch_blocks(nir_block *before, nir_block *after)
|
||||||
exec_node_remove(&after->cf_node.node);
|
exec_node_remove(&after->cf_node.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_defs_uses(nir_instr *instr);
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup_cf_node(nir_cf_node *node)
|
||||||
|
{
|
||||||
|
switch (node->type) {
|
||||||
|
case nir_cf_node_block: {
|
||||||
|
nir_block *block = nir_cf_node_as_block(node);
|
||||||
|
/* We need to walk the instructions and clean up defs/uses */
|
||||||
|
nir_foreach_instr(block, instr)
|
||||||
|
remove_defs_uses(instr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nir_cf_node_if: {
|
||||||
|
nir_if *if_stmt = nir_cf_node_as_if(node);
|
||||||
|
foreach_list_typed(nir_cf_node, child, node, &if_stmt->then_list)
|
||||||
|
cleanup_cf_node(child);
|
||||||
|
foreach_list_typed(nir_cf_node, child, node, &if_stmt->else_list)
|
||||||
|
cleanup_cf_node(child);
|
||||||
|
|
||||||
|
struct set *if_uses;
|
||||||
|
if (if_stmt->condition.is_ssa) {
|
||||||
|
if_uses = if_stmt->condition.ssa->if_uses;
|
||||||
|
} else {
|
||||||
|
if_uses = if_stmt->condition.reg.reg->if_uses;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct set_entry *entry = _mesa_set_search(if_uses, if_stmt);
|
||||||
|
assert(entry);
|
||||||
|
_mesa_set_remove(if_uses, entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nir_cf_node_loop: {
|
||||||
|
nir_loop *loop = nir_cf_node_as_loop(node);
|
||||||
|
foreach_list_typed(nir_cf_node, child, node, &loop->body)
|
||||||
|
cleanup_cf_node(child);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case nir_cf_node_function: {
|
||||||
|
nir_function_impl *impl = nir_cf_node_as_function(node);
|
||||||
|
foreach_list_typed(nir_cf_node, child, node, &impl->body)
|
||||||
|
cleanup_cf_node(child);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
unreachable("Invalid CF node type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nir_cf_node_remove(nir_cf_node *node)
|
nir_cf_node_remove(nir_cf_node *node)
|
||||||
{
|
{
|
||||||
|
@ -1177,6 +1229,8 @@ nir_cf_node_remove(nir_cf_node *node)
|
||||||
exec_node_remove(&node->node);
|
exec_node_remove(&node->node);
|
||||||
stitch_blocks(before_block, after_block);
|
stitch_blocks(before_block, after_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup_cf_node(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
Loading…
Reference in New Issue