agx: Make partial DCE optional
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Fri, 3 Mar 2023 05:12:00 +0000 (00:12 -0500)
committerMarge Bot <emma+marge@anholt.net>
Sat, 11 Mar 2023 14:15:50 +0000 (14:15 +0000)
Our dead code elimination pass does two things:

1. delete instructions that are entirely unnecessary
2. delete unnecessary destinations of necessary instructions

To deal with pass ordering issues, we sometimes want to do #1 without #2.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21674>

src/asahi/compiler/agx_compile.c
src/asahi/compiler/agx_compiler.h
src/asahi/compiler/agx_dce.c
src/asahi/compiler/test/test-optimizer.cpp

index 06328db..06f6d3b 100644 (file)
@@ -2144,7 +2144,7 @@ agx_compile_function_nir(nir_shader *nir, nir_function_impl *impl,
    if (likely(!(agx_compiler_debug & AGX_DBG_NOOPT))) {
       /* Dead code eliminate before instruction combining so use counts are
        * right */
-      agx_dce(ctx);
+      agx_dce(ctx, true);
       agx_optimizer(ctx);
       agx_opt_cse(ctx);
 
@@ -2155,7 +2155,7 @@ agx_compile_function_nir(nir_shader *nir, nir_function_impl *impl,
       agx_lower_uniform_sources(ctx);
 
       /* Dead code eliminate after instruction combining to get the benefit */
-      agx_dce(ctx);
+      agx_dce(ctx, true);
       agx_validate(ctx, "Optimization");
 
       if (agx_should_dump(nir, AGX_DBG_SHADERS))
index 5eb3441..6412b68 100644 (file)
@@ -774,7 +774,7 @@ void agx_optimizer(agx_context *ctx);
 void agx_lower_pseudo(agx_context *ctx);
 void agx_lower_uniform_sources(agx_context *ctx);
 void agx_opt_cse(agx_context *ctx);
-void agx_dce(agx_context *ctx);
+void agx_dce(agx_context *ctx, bool partial);
 void agx_ra(agx_context *ctx);
 void agx_lower_64bit_postra(agx_context *ctx);
 void agx_insert_waits(agx_context *ctx);
index 58450df..74e8036 100644 (file)
@@ -26,7 +26,7 @@
 /* SSA-based scalar dead code elimination */
 
 void
-agx_dce(agx_context *ctx)
+agx_dce(agx_context *ctx, bool partial)
 {
    bool progress;
    do {
@@ -47,18 +47,16 @@ agx_dce(agx_context *ctx)
 
          bool needed = false;
 
-         agx_foreach_dest(I, d) {
+         agx_foreach_ssa_dest(I, d) {
             /* Eliminate destinations that are never read, as RA needs to
              * handle them specially. Visible only for instructions that write
              * multiple destinations (splits) or that write a destination but
              * cannot be DCE'd (atomics).
              */
-            if ((I->dest[d].type == AGX_INDEX_NORMAL) &&
-                !BITSET_TEST(seen, I->dest[d].value))
+            if (BITSET_TEST(seen, I->dest[d].value))
+               needed = true;
+            else if (partial)
                I->dest[d] = agx_null();
-
-            /* If the destination is actually needed, the instruction is too */
-            needed |= (I->dest[d].type != AGX_INDEX_NULL);
          }
 
          if (!needed) {
index 980cee9..9a23642 100644 (file)
@@ -29,7 +29,7 @@ static void
 agx_optimize_and_dce(agx_context *ctx)
 {
    agx_optimizer(ctx);
-   agx_dce(ctx);
+   agx_dce(ctx, true);
 }
 
 #define CASE(instr, expected, size)                                            \