summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuan A. Suarez Romero <[email protected]>2019-02-12 12:02:42 +0000
committerJuan A. Suarez Romero <[email protected]>2019-02-15 15:16:24 +0100
commit1fb24080b7da8c1378c7aabc2d02ffece677ce7c (patch)
treed4e09939c129175296c4068b56715d98591ed0ea
parent69be9934a780eadc7c0b64465fae8431eb979dae (diff)
nir: remove jump from two merging jump-ending blocks
In opt_peel_initial_if optimization, when moving the continue list to end of the continue block, before the jump, could happen that the continue list itself also ends with a jump. This would mean that we would have two jump instructions in a row: the first one from the continue list and the second one from the contine block. As inserting an instruction after a jump is not allowed (and it does not make sense, as it will not be executed), remove the jump from the continue block and keep the one from continue list, as it will be executed first. CC: Jason Ekstrand <[email protected]> Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>
-rw-r--r--src/compiler/nir/nir_opt_if.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c
index 60846de3a1f..bc128f79f3c 100644
--- a/src/compiler/nir/nir_opt_if.c
+++ b/src/compiler/nir/nir_opt_if.c
@@ -241,12 +241,29 @@ opt_peel_loop_initial_if(nir_loop *loop)
nir_cf_reinsert(&header,
nir_after_block_before_jump(find_continue_block(loop)));
+ bool continue_list_jumps =
+ nir_block_ends_in_jump(exec_node_data(nir_block,
+ exec_list_get_tail(continue_list),
+ cf_node.node));
+
nir_cf_extract(&tmp, nir_before_cf_list(continue_list),
nir_after_cf_list(continue_list));
- /* Get continue block again as the previous reinsert might have removed the block. */
+ /* Get continue block again as the previous reinsert might have removed the
+ * block. Also, if both the continue list and the continue block ends in
+ * jump instructions, removes the jump from the latter, as it will not be
+ * executed if we insert the continue list before it. */
+
+ nir_block *continue_block = find_continue_block(loop);
+
+ if (continue_list_jumps) {
+ nir_instr *last_instr = nir_block_last_instr(continue_block);
+ if (last_instr && last_instr->type == nir_instr_type_jump)
+ nir_instr_remove(last_instr);
+ }
+
nir_cf_reinsert(&tmp,
- nir_after_block_before_jump(find_continue_block(loop)));
+ nir_after_block_before_jump(continue_block));
nir_cf_node_remove(&nif->cf_node);