new_block->cf_node.parent = block->cf_node.parent;
exec_node_insert_node_before(&block->cf_node.node, &new_block->cf_node.node);
- struct set_entry *entry;
set_foreach(block->predecessors, entry) {
nir_block *pred = (nir_block *) entry->key;
replace_successor(pred, block, new_block);
}
/* Any phi nodes must stay part of the new block, or else their
- * sourcse will be messed up. This will reverse the order of the phis, but
- * order shouldn't matter.
+ * sources will be messed up.
*/
nir_foreach_instr_safe(instr, block) {
if (instr->type != nir_instr_type_phi)
exec_node_remove(&instr->node);
instr->block = new_block;
- exec_list_push_head(&new_block->instr_list, &instr->node);
+ exec_list_push_tail(&new_block->instr_list, &instr->node);
}
return new_block;
return nir_cf_node_as_loop(node);
}
+static void
+remove_phi_src(nir_block *block, nir_block *pred)
+{
+ nir_foreach_instr(instr, block) {
+ if (instr->type != nir_instr_type_phi)
+ break;
+
+ nir_phi_instr *phi = nir_instr_as_phi(instr);
+ nir_foreach_phi_src_safe(src, phi) {
+ if (src->pred == pred) {
+ list_del(&src->src.use_link);
+ exec_node_remove(&src->node);
+ }
+ }
+ }
+}
+
/*
* update the CFG after a jump instruction has been added to the end of a block
*/
nir_instr *instr = nir_block_last_instr(block);
nir_jump_instr *jump_instr = nir_instr_as_jump(instr);
+ if (block->successors[0])
+ remove_phi_src(block->successors[0], block);
+ if (block->successors[1])
+ remove_phi_src(block->successors[1], block);
unlink_block_successors(block);
nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);
nir_metadata_preserve(impl, nir_metadata_none);
- if (jump_instr->type == nir_jump_break ||
- jump_instr->type == nir_jump_continue) {
- nir_loop *loop = nearest_loop(&block->cf_node);
-
- if (jump_instr->type == nir_jump_continue) {
- nir_block *first_block = nir_loop_first_block(loop);
- link_blocks(block, first_block, NULL);
- } else {
- nir_cf_node *after = nir_cf_node_next(&loop->cf_node);
- nir_block *after_block = nir_cf_node_as_block(after);
- link_blocks(block, after_block, NULL);
- }
- } else {
- assert(jump_instr->type == nir_jump_return);
+ switch (jump_instr->type) {
+ case nir_jump_return:
link_blocks(block, impl->end_block, NULL);
+ break;
+
+ case nir_jump_break: {
+ nir_loop *loop = nearest_loop(&block->cf_node);
+ nir_cf_node *after = nir_cf_node_next(&loop->cf_node);
+ nir_block *after_block = nir_cf_node_as_block(after);
+ link_blocks(block, after_block, NULL);
+ break;
}
-}
-static void
-remove_phi_src(nir_block *block, nir_block *pred)
-{
- nir_foreach_instr(instr, block) {
- if (instr->type != nir_instr_type_phi)
- break;
+ case nir_jump_continue: {
+ nir_loop *loop = nearest_loop(&block->cf_node);
+ nir_block *first_block = nir_loop_first_block(loop);
+ link_blocks(block, first_block, NULL);
+ break;
+ }
- nir_phi_instr *phi = nir_instr_as_phi(instr);
- nir_foreach_phi_src_safe(src, phi) {
- if (src->pred == pred) {
- list_del(&src->src.use_link);
- exec_node_remove(&src->node);
- }
- }
+ default:
+ unreachable("Invalid jump type");
}
}