summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/nir/nir_opt_loop_unroll.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/compiler/nir/nir_opt_loop_unroll.c b/src/compiler/nir/nir_opt_loop_unroll.c
index dae5bfc9020..0e9cb500b58 100644
--- a/src/compiler/nir/nir_opt_loop_unroll.c
+++ b/src/compiler/nir/nir_opt_loop_unroll.c
@@ -39,10 +39,10 @@
#define LOOP_UNROLL_LIMIT 96
/* Prepare this loop for unrolling by first converting to lcssa and then
- * converting the phis from the loops first block and the block that follows
- * the loop into regs. Partially converting out of SSA allows us to unroll
- * the loop without having to keep track of and update phis along the way
- * which gets tricky and doesn't add much value over conveting to regs.
+ * converting the phis from the top level of the loop body to regs.
+ * Partially converting out of SSA allows us to unroll the loop without having
+ * to keep track of and update phis along the way which gets tricky and
+ * doesn't add much value over converting to regs.
*
* The loop may have a continue instruction at the end of the loop which does
* nothing. Once we're out of SSA, we can safely delete it so we don't have
@@ -53,13 +53,20 @@ loop_prepare_for_unroll(nir_loop *loop)
{
nir_convert_loop_to_lcssa(loop);
- nir_lower_phis_to_regs_block(nir_loop_first_block(loop));
+ /* Lower phis at the top level of the loop body */
+ foreach_list_typed_safe(nir_cf_node, node, node, &loop->body) {
+ if (nir_cf_node_block == node->type) {
+ nir_lower_phis_to_regs_block(nir_cf_node_as_block(node));
+ }
+ }
+ /* Lower phis after the loop */
nir_block *block_after_loop =
nir_cf_node_as_block(nir_cf_node_next(&loop->cf_node));
nir_lower_phis_to_regs_block(block_after_loop);
+ /* Remove continue if its the last instruction in the loop */
nir_instr *last_instr = nir_block_last_instr(nir_loop_last_block(loop));
if (last_instr && last_instr->type == nir_instr_type_jump) {
assert(nir_instr_as_jump(last_instr)->type == nir_jump_continue);