nir/cf: handle jumps better in stitch_blocks()
authorConnor Abbott <cwabbott0@gmail.com>
Wed, 22 Jul 2015 02:54:26 +0000 (19:54 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 24 Aug 2015 20:31:42 +0000 (13:31 -0700)
In particular, handle the case where the earlier block ends in a jump
and the later block is empty. In that case, we want to preserve the jump
and remove any traces of the later block. Before, we would only hit this
case when removing a control flow node after a jump, which wasn't a
common occurance, but we'll need it to handle inserting a control flow
list which ends in a jump, which should be more common/useful.

Signed-off-by: Connor Abbott <connor.w.abbott@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/nir/nir_control_flow.c

index 1f2a681f2587d064522caf8d657df012a5931827..8a4a0bf5f9dff22c093b0662781d38284c0cdce6 100644 (file)
@@ -706,14 +706,24 @@ stitch_blocks(nir_block *before, nir_block *after)
     * TODO: special case when before is empty and after isn't?
     */
 
-   move_successors(after, before);
+   if (block_ends_in_jump(before)) {
+      assert(exec_list_is_empty(&after->instr_list));
+      if (after->successors[0])
+         remove_phi_src(after->successors[0], after);
+      if (after->successors[1])
+         remove_phi_src(after->successors[1], after);
+      unlink_block_successors(after);
+      exec_node_remove(&after->cf_node.node);
+   } else {
+      move_successors(after, before);
 
-   foreach_list_typed(nir_instr, instr, node, &after->instr_list) {
-      instr->block = before;
-   }
+      foreach_list_typed(nir_instr, instr, node, &after->instr_list) {
+         instr->block = before;
+      }
 
-   exec_list_append(&before->instr_list, &after->instr_list);
-   exec_node_remove(&after->cf_node.node);
+      exec_list_append(&before->instr_list, &after->instr_list);
+      exec_node_remove(&after->cf_node.node);
+   }
 }