nir/trivialize: Move decl_reg to the start of the block
authorIago Toral Quiroga <itoral@igalia.com>
Thu, 20 Jul 2023 09:16:07 +0000 (11:16 +0200)
committerMarge Bot <emma+marge@anholt.net>
Tue, 25 Jul 2023 15:36:52 +0000 (15:36 +0000)
This makes it so we never find a reg_decl in between a reg_store and the def
for its value, which helps avid inserting copy movs.

Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24153>

src/compiler/nir/nir_trivialize_registers.c

index 665b2ab..6ce2472 100644 (file)
  * This pass inserts copies to ensure that all load_reg/store_reg are trivial.
  */
 
+/*
+ * In order to allow for greater freedom elsewhere in the pass, move all
+ * reg_decl intrinsics to the top of their block.  This ensures in particular
+ * that decl_reg intrinsics occur before the producer of the SSA value
+ * consumed by a store_reg whenever they're all in the same block.
+ */
+static void
+move_reg_decls(nir_block *block)
+{
+   nir_cursor cursor = nir_before_block(block);
+
+   nir_foreach_instr_safe(instr, block) {
+      if (instr->type != nir_instr_type_intrinsic)
+         continue;
+
+      nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
+      if (intr->intrinsic != nir_intrinsic_decl_reg)
+         continue;
+
+      nir_instr_move(cursor, instr);
+      cursor = nir_after_instr(instr);
+   }
+}
+
  /*
  * Any load can be trivialized by copying immediately after the load and then
  * rewriting uses of the load to read from the copy. That has no functional
@@ -459,6 +483,9 @@ void
 nir_trivialize_registers(nir_shader *s)
 {
    nir_foreach_function_impl(impl, s) {
+      /* All decl_reg intrinsics are in the start block. */
+      move_reg_decls(nir_start_block(impl));
+
       nir_foreach_block(block, impl) {
          trivialize_loads(impl, block);
          trivialize_stores(impl, block);