unlink_block_successors(block);
link_blocks(block, first_then_block, first_else_block);
- } else {
+ } else if (node->type == nir_cf_node_loop) {
/*
* For similar reasons as the corresponding case in
* link_non_block_to_block(), don't worry about if the loop header has
}
/* 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;
nir_block *first_else_block = nir_if_first_else_block(next_if);
link_blocks(block, first_then_block, first_else_block);
- } else {
+ } else if (next->type == nir_cf_node_loop) {
nir_loop *next_loop = nir_cf_node_as_loop(next);
nir_block *first_block = nir_loop_first_block(next_loop);
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) {
+ 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;
+ }
- 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);
- link_blocks(block, impl->end_block, NULL);
+ 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;
+ }
+
+ case nir_jump_goto:
+ link_blocks(block, jump_instr->target, NULL);
+ break;
+
+ case nir_jump_goto_if:
+ link_blocks(block, jump_instr->else_target, jump_instr->target);
+ break;
+
+ default:
+ unreachable("Invalid jump type");
}
}
/* We need to walk the instructions and clean up defs/uses */
nir_foreach_instr_safe(instr, block) {
if (instr->type == nir_instr_type_jump) {
- nir_jump_type jump_type = nir_instr_as_jump(instr)->type;
- unlink_jump(block, jump_type, false);
+ nir_jump_instr *jump = nir_instr_as_jump(instr);
+ unlink_jump(block, jump->type, false);
+ if (jump->type == nir_jump_goto_if)
+ nir_instr_rewrite_src(instr, &jump->condition, NIR_SRC_INIT);
} else {
nir_foreach_ssa_def(instr, replace_ssa_def_uses, impl);
nir_instr_remove(instr);