Mesa (main): nir/loop_unroll: clean up after complex_unroll_single_terminator()

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 20 04:22:44 UTC 2022


Module: Mesa
Branch: main
Commit: d1e36634bdf3178f8ae7290de14bb9122cebe550
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d1e36634bdf3178f8ae7290de14bb9122cebe550

Author: Timothy Arceri <tarceri at itsqueeze.com>
Date:   Mon Jul 18 19:18:15 2022 +1000

nir/loop_unroll: clean up after complex_unroll_single_terminator()

Previously we would just unroll the loop one extra iteration and let
other optimisation passes clean up the mess. This worked to a degree
but if the loop happened to be nested inside another loop we would
end up with phi chains that would block other passes from being able
to do the cleanup.

With this commit we explicitly clone the variables create by lcsaa
and insert them directly in the last continue branch after we are done
unrolling. With this optimisation passes can recognise both sides
of the if output the same values and can progress further.

Help with the issues described in:
https://gitlab.freedesktop.org/mesa/mesa/-/issues/6051

Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17611>

---

 src/compiler/nir/nir_opt_loop_unroll.c | 35 ++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/src/compiler/nir/nir_opt_loop_unroll.c b/src/compiler/nir/nir_opt_loop_unroll.c
index d101d74c5d7..095fd02548c 100644
--- a/src/compiler/nir/nir_opt_loop_unroll.c
+++ b/src/compiler/nir/nir_opt_loop_unroll.c
@@ -495,6 +495,41 @@ complex_unroll_single_terminator(nir_loop *loop)
       complex_unroll_loop_body(loop, terminator, &lp_header, &lp_body,
                                remap_table, num_times_to_clone);
 
+   assert(unroll_loc->type == nir_cf_node_if);
+
+   /* We need to clone the lcssa vars in order to insert them on both sides
+    * of the if in the last iteration/if-statement. Otherwise the optimisation
+    * passes will have trouble optimising the unrolled if ladder.
+    */
+   nir_cursor cursor =
+      get_complex_unroll_insert_location(unroll_loc,
+                                         terminator->continue_from_then);
+
+   nir_if *if_stmt = nir_cf_node_as_if(unroll_loc);
+   nir_cursor start_cursor;
+   nir_cursor end_cursor;
+   if (terminator->continue_from_then) {
+      start_cursor = nir_before_block(nir_if_first_else_block(if_stmt));
+      end_cursor = nir_after_block(nir_if_last_else_block(if_stmt));
+   } else {
+      start_cursor = nir_before_block(nir_if_first_then_block(if_stmt));
+      end_cursor = nir_after_block(nir_if_last_then_block(if_stmt));
+   }
+
+   nir_cf_list lcssa_list;
+   nir_cf_extract(&lcssa_list, start_cursor, end_cursor);
+
+   /* Insert the cloned vars in the last continue branch */
+   nir_cf_list_clone_and_reinsert(&lcssa_list, loop->cf_node.parent,
+                                  cursor, remap_table);
+
+   start_cursor = terminator->continue_from_then ?
+      nir_before_block(nir_if_first_else_block(if_stmt)) :
+      nir_before_block(nir_if_first_then_block(if_stmt));
+
+   /* Reinsert the cloned vars back where they came from */
+   nir_cf_reinsert(&lcssa_list, start_cursor);
+
    /* Delete the original loop header and body */
    nir_cf_delete(&lp_header);
    nir_cf_delete(&lp_body);



More information about the mesa-commit mailing list