Mesa (main): ir3: Retire the cp postsched pass now that we do RA in SSA.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jul 4 22:53:14 UTC 2022


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

Author: Emma Anholt <emma at anholt.net>
Date:   Thu Jun 30 11:50:11 2022 -0700

ir3: Retire the cp postsched pass now that we do RA in SSA.

Before, we needed CP post-sched to copy-propagate references to NIR
registers produced by out-of-ssa.  Now that we're in SSA, this pass ends
up not doing anything useful, and actually gets in the way by occasionally
creating a cycle in the DAG.

The entire shader-db impact is:

instructions HURT:   shaders/closed/steam/tropico-5/78.shader_test FRAG: 238 -> 242 (1.68%)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17320>

---

 src/freedreno/ir3/ir3.h              |   1 -
 src/freedreno/ir3/ir3_compiler_nir.c |   6 -
 src/freedreno/ir3/ir3_cp_postsched.c | 233 -----------------------------------
 src/freedreno/ir3/meson.build        |   1 -
 4 files changed, 241 deletions(-)

diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h
index 2d94c3a7d2b..22cea029494 100644
--- a/src/freedreno/ir3/ir3.h
+++ b/src/freedreno/ir3/ir3.h
@@ -1843,7 +1843,6 @@ bool ir3_cf(struct ir3 *ir);
 
 /* copy-propagate: */
 bool ir3_cp(struct ir3 *ir, struct ir3_shader_variant *so);
-bool ir3_cp_postsched(struct ir3 *ir);
 
 /* common subexpression elimination: */
 bool ir3_cse(struct ir3 *ir);
diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index f451cc91321..7ac829a49ce 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -4822,12 +4822,6 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
 
    ir3_debug_print(ir, "AFTER: ir3_sched");
 
-   if (IR3_PASS(ir, ir3_cp_postsched)) {
-      /* cleanup the result of removing unneeded mov's: */
-      while (IR3_PASS(ir, ir3_dce, so)) {
-      }
-   }
-
    /* Pre-assign VS inputs on a6xx+ binning pass shader, to align
     * with draw pass VS, so binning and draw pass can both use the
     * same VBO state.
diff --git a/src/freedreno/ir3/ir3_cp_postsched.c b/src/freedreno/ir3/ir3_cp_postsched.c
deleted file mode 100644
index dca18367f63..00000000000
--- a/src/freedreno/ir3/ir3_cp_postsched.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright © 2020 Google, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "util/ralloc.h"
-#include "util/u_dynarray.h"
-
-#include "ir3.h"
-
-/**
- * A bit more extra cleanup after sched pass.  In particular, prior to
- * instruction scheduling, we can't easily eliminate unneeded mov's
- * from "arrays", because we don't yet know if there is an intervening
- * array-write scheduled before the use of the array-read.
- *
- * NOTE array is equivalent to nir "registers".. ie. it can be length of
- * one.  It is basically anything that is not SSA.
- */
-
-/**
- * Check if any instruction before `use` and after `src` writes to the
- * specified array.  If `offset` is negative, it is a relative (a0.x)
- * access and we care about all writes to the array (as we don't know
- * which array element is read).  Otherwise in the case of non-relative
- * access, we only have to care about the write to the specified (>= 0)
- * offset. In this case, we update `def` to point to the last write in
- * between `use` and `src` to the same array, so that `use` points to
- * the correct array write.
- */
-static bool
-has_conflicting_write(struct ir3_instruction *src, struct ir3_instruction *use,
-                      struct ir3_register **def, unsigned id, int offset)
-{
-   assert(src->block == use->block);
-   bool last_write = true;
-
-   /* NOTE that since src and use are in the same block, src by
-    * definition appears in the block's instr_list before use:
-    */
-   foreach_instr_rev (instr, &use->node) {
-      if (instr == src)
-         break;
-
-      foreach_dst (dst, instr) {
-         /* if we are looking at a RELATIV read, we can't move
-          * it past an a0.x write:
-          */
-         if (dst->num == regid(REG_A0, 0))
-            return true;
-
-         if (!is_dest_gpr(dst))
-            continue;
-
-         if (!(dst->flags & IR3_REG_ARRAY))
-            continue;
-
-         if (dst->array.id != id)
-            continue;
-
-         /*
-          * At this point, we have narrowed down an instruction
-          * that writes to the same array.. check if it the write
-          * is to an array element that we care about:
-          */
-
-         /* is write to an unknown array element? */
-         if (dst->flags & IR3_REG_RELATIV)
-            return true;
-
-         /* is read from an unknown array element? */
-         if (offset < 0)
-            return true;
-
-         /* is write to same array element? */
-         if (dst->array.offset == offset)
-            return true;
-
-         if (last_write)
-            *def = dst;
-
-         last_write = false;
-      }
-   }
-
-   return false;
-}
-
-/* Can we fold the mov src into use without invalid flags? */
-static bool
-valid_flags(struct ir3_instruction *use, struct ir3_instruction *mov)
-{
-   struct ir3_register *src = mov->srcs[0];
-
-   foreach_src_n (reg, n, use) {
-      if (ssa(reg) != mov)
-         continue;
-
-      if (!ir3_valid_flags(use, n, reg->flags | src->flags))
-         return false;
-   }
-
-   return true;
-}
-
-static bool
-instr_cp_postsched(struct ir3_instruction *mov)
-{
-   struct ir3_register *src = mov->srcs[0];
-
-   /* only consider mov's from "arrays", other cases we have
-    * already considered already:
-    */
-   if (!(src->flags & IR3_REG_ARRAY))
-      return false;
-
-   int offset = (src->flags & IR3_REG_RELATIV) ? -1 : src->array.offset;
-
-   /* Once we move the array read directly into the consuming
-    * instruction(s), we will also need to update instructions
-    * that had a false-dep on the original mov to have deps
-    * on the consuming instructions:
-    */
-   struct util_dynarray newdeps;
-   util_dynarray_init(&newdeps, mov->uses);
-
-   foreach_ssa_use (use, mov) {
-      if (use->block != mov->block)
-         continue;
-
-      if (is_meta(use))
-         continue;
-
-      if (is_subgroup_cond_mov_macro(use))
-         continue;
-
-      struct ir3_register *def = src->def;
-      if (has_conflicting_write(mov, use, &def, src->array.id, offset))
-         continue;
-
-      if (conflicts(mov->address, use->address))
-         continue;
-
-      if (!valid_flags(use, mov))
-         continue;
-
-      /* Ok, we've established that it is safe to remove this copy: */
-
-      bool removed = false;
-      foreach_src_n (reg, n, use) {
-         if (ssa(reg) != mov)
-            continue;
-
-         use->srcs[n] = ir3_reg_clone(mov->block->shader, src);
-
-         /* preserve (abs)/etc modifiers: */
-         use->srcs[n]->flags |= reg->flags;
-
-         /* If we're sinking the array read past any writes, make
-          * sure to update it to point to the new previous write:
-          */
-         use->srcs[n]->def = def;
-
-         removed = true;
-      }
-
-      /* the use could have been only a false-dep, only add to the newdeps
-       * array and update the address if we've actually updated a real src
-       * reg for the use:
-       */
-      if (removed) {
-         if (src->flags & IR3_REG_RELATIV)
-            ir3_instr_set_address(use, mov->address->def->instr);
-
-         util_dynarray_append(&newdeps, struct ir3_instruction *, use);
-
-         /* Remove the use from the src instruction: */
-         _mesa_set_remove_key(mov->uses, use);
-      }
-   }
-
-   /* Once we have the complete set of instruction(s) that are are now
-    * directly reading from the array, update any false-dep uses to
-    * now depend on these instructions.  The only remaining uses at
-    * this point should be false-deps:
-    */
-   foreach_ssa_use (use, mov) {
-      util_dynarray_foreach (&newdeps, struct ir3_instruction *, instrp) {
-         struct ir3_instruction *newdep = *instrp;
-         ir3_instr_add_dep(use, newdep);
-      }
-   }
-
-   return util_dynarray_num_elements(&newdeps, struct ir3_instruction **) > 0;
-}
-
-bool
-ir3_cp_postsched(struct ir3 *ir)
-{
-   void *mem_ctx = ralloc_context(NULL);
-   bool progress = false;
-
-   ir3_find_ssa_uses(ir, mem_ctx, false);
-
-   foreach_block (block, &ir->block_list) {
-      foreach_instr_safe (instr, &block->instr_list) {
-         if (is_same_type_mov(instr))
-            progress |= instr_cp_postsched(instr);
-      }
-   }
-
-   ralloc_free(mem_ctx);
-
-   return progress;
-}
diff --git a/src/freedreno/ir3/meson.build b/src/freedreno/ir3/meson.build
index 031f0220da9..7dc641bbe83 100644
--- a/src/freedreno/ir3/meson.build
+++ b/src/freedreno/ir3/meson.build
@@ -76,7 +76,6 @@ libfreedreno_ir3_files = files(
   'ir3_context.h',
   'ir3_cf.c',
   'ir3_cp.c',
-  'ir3_cp_postsched.c',
   'ir3_cse.c',
   'ir3_dce.c',
   'ir3_delay.c',



More information about the mesa-commit mailing list