agx: Make partial DCE optional

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>
This commit is contained in:
Alyssa Rosenzweig
2023-03-03 00:12:00 -05:00
committed by Marge Bot
parent 16f8bfb042
commit 5ea9c2e634
4 changed files with 9 additions and 11 deletions

View File

@@ -2144,7 +2144,7 @@ agx_compile_function_nir(nir_shader *nir, nir_function_impl *impl,
if (likely(!(agx_compiler_debug & AGX_DBG_NOOPT))) { if (likely(!(agx_compiler_debug & AGX_DBG_NOOPT))) {
/* Dead code eliminate before instruction combining so use counts are /* Dead code eliminate before instruction combining so use counts are
* right */ * right */
agx_dce(ctx); agx_dce(ctx, true);
agx_optimizer(ctx); agx_optimizer(ctx);
agx_opt_cse(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); agx_lower_uniform_sources(ctx);
/* Dead code eliminate after instruction combining to get the benefit */ /* Dead code eliminate after instruction combining to get the benefit */
agx_dce(ctx); agx_dce(ctx, true);
agx_validate(ctx, "Optimization"); agx_validate(ctx, "Optimization");
if (agx_should_dump(nir, AGX_DBG_SHADERS)) if (agx_should_dump(nir, AGX_DBG_SHADERS))

View File

@@ -774,7 +774,7 @@ void agx_optimizer(agx_context *ctx);
void agx_lower_pseudo(agx_context *ctx); void agx_lower_pseudo(agx_context *ctx);
void agx_lower_uniform_sources(agx_context *ctx); void agx_lower_uniform_sources(agx_context *ctx);
void agx_opt_cse(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_ra(agx_context *ctx);
void agx_lower_64bit_postra(agx_context *ctx); void agx_lower_64bit_postra(agx_context *ctx);
void agx_insert_waits(agx_context *ctx); void agx_insert_waits(agx_context *ctx);

View File

@@ -26,7 +26,7 @@
/* SSA-based scalar dead code elimination */ /* SSA-based scalar dead code elimination */
void void
agx_dce(agx_context *ctx) agx_dce(agx_context *ctx, bool partial)
{ {
bool progress; bool progress;
do { do {
@@ -47,18 +47,16 @@ agx_dce(agx_context *ctx)
bool needed = false; bool needed = false;
agx_foreach_dest(I, d) { agx_foreach_ssa_dest(I, d) {
/* Eliminate destinations that are never read, as RA needs to /* Eliminate destinations that are never read, as RA needs to
* handle them specially. Visible only for instructions that write * handle them specially. Visible only for instructions that write
* multiple destinations (splits) or that write a destination but * multiple destinations (splits) or that write a destination but
* cannot be DCE'd (atomics). * cannot be DCE'd (atomics).
*/ */
if ((I->dest[d].type == AGX_INDEX_NORMAL) && if (BITSET_TEST(seen, I->dest[d].value))
!BITSET_TEST(seen, I->dest[d].value)) needed = true;
else if (partial)
I->dest[d] = agx_null(); 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) { if (!needed) {

View File

@@ -29,7 +29,7 @@ static void
agx_optimize_and_dce(agx_context *ctx) agx_optimize_and_dce(agx_context *ctx)
{ {
agx_optimizer(ctx); agx_optimizer(ctx);
agx_dce(ctx); agx_dce(ctx, true);
} }
#define CASE(instr, expected, size) \ #define CASE(instr, expected, size) \