/**
* Stitch two basic blocks together into one. The aggregate must have the same
* predecessors as the first and the same successors as the second.
+ *
+ * Returns a cursor pointing at the end of the before block (i.e.m between the
+ * two blocks) once stiched together.
*/
-static void
+static nir_cursor
stitch_blocks(nir_block *before, nir_block *after)
{
/*
remove_phi_src(after->successors[1], after);
unlink_block_successors(after);
exec_node_remove(&after->cf_node.node);
+
+ return nir_after_block(before);
} else {
+ nir_instr *last_before_instr = nir_block_last_instr(before);
+
move_successors(after, before);
foreach_list_typed(nir_instr, instr, node, &after->instr_list) {
exec_list_append(&before->instr_list, &after->instr_list);
exec_node_remove(&after->cf_node.node);
+
+ return last_before_instr ? nir_after_instr(last_before_instr) :
+ nir_before_block(before);
}
}
}
}
-void
+/**
+ * Inserts a list at a given cursor. Returns the cursor at the end of the
+ * insertion (i.e., at the end of the instructions contained in cf_list).
+ */
+nir_cursor
nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor)
{
nir_block *before, *after;
if (exec_list_is_empty(&cf_list->list))
- return;
+ return cursor;
nir_function_impl *cursor_impl =
nir_cf_node_get_function(&nir_cursor_current_block(cursor)->cf_node);
stitch_blocks(before,
nir_cf_node_as_block(nir_cf_node_next(&before->cf_node)));
- stitch_blocks(nir_cf_node_as_block(nir_cf_node_prev(&after->cf_node)),
- after);
+ return stitch_blocks(nir_cf_node_as_block(nir_cf_node_prev(&after->cf_node)),
+ after);
}
void