From d39b1c342617c5060243eb20833fd5e8deadb0fd Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Tue, 12 Apr 2022 19:27:00 -0400 Subject: [PATCH] agx: Implement simple copyprop Cleans up some of the mess. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/compiler/agx_optimizer.c | 26 +++++++++++++++ src/asahi/compiler/test/test-optimizer.cpp | 38 ++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/asahi/compiler/agx_optimizer.c b/src/asahi/compiler/agx_optimizer.c index 0e6de7ee842..57549d24010 100644 --- a/src/asahi/compiler/agx_optimizer.c +++ b/src/asahi/compiler/agx_optimizer.c @@ -151,6 +151,29 @@ agx_optimizer_fmov_rev(agx_instr *I, agx_instr *use) return true; } +static void +agx_optimizer_copyprop(agx_instr **defs, agx_instr *I, unsigned srcs) +{ + for (unsigned s = 0; s < srcs; ++s) { + agx_index src = I->src[s]; + if (src.type != AGX_INDEX_NORMAL) continue; + + agx_instr *def = defs[src.value]; + if (def->op != AGX_OPCODE_MOV) continue; + + /* At the moment, not all instructions support size conversions. Notably + * RA pseudo instructions don't handle size conversions. This should be + * refined in the future. + */ + if (def->src[0].size != src.size) continue; + + /* Immediate inlining happens elsewhere */ + if (def->src[0].type == AGX_INDEX_IMMEDIATE) continue; + + I->src[s] = agx_replace_index(src, def->src[0]); + } +} + static void agx_optimizer_forward(agx_context *ctx) { @@ -164,6 +187,9 @@ agx_optimizer_forward(agx_context *ctx) defs[I->dest[d].value] = I; } + /* Optimize moves */ + agx_optimizer_copyprop(defs, I, info.nr_srcs); + /* Propagate fmov down */ if (info.is_float) agx_optimizer_fmov(defs, I, info.nr_srcs); diff --git a/src/asahi/compiler/test/test-optimizer.cpp b/src/asahi/compiler/test/test-optimizer.cpp index 2591c3158fb..338a9596ae6 100644 --- a/src/asahi/compiler/test/test-optimizer.cpp +++ b/src/asahi/compiler/test/test-optimizer.cpp @@ -72,3 +72,41 @@ TEST_F(Optimizer, FusedFABSNEG) CASE(agx_fmul_to(b, wz, wx, agx_fmov(b, agx_neg(agx_abs(wx)))), agx_fmul_to(b, wz, wx, agx_neg(agx_abs(wx)))); } + +TEST_F(Optimizer, Copyprop) +{ + CASE(agx_fmul_to(b, wz, wx, agx_mov(b, wy)), agx_fmul_to(b, wz, wx, wy)); + CASE(agx_fmul_to(b, wz, agx_mov(b, wx), agx_mov(b, wy)), agx_fmul_to(b, wz, wx, wy)); +} + +TEST_F(Optimizer, InlineHazards) +{ + NEGCASE(agx_p_combine_to(b, wx, agx_mov_imm(b, AGX_SIZE_32, 0), wy, wz, wz)); +} + +TEST_F(Optimizer, CopypropRespectsAbsNeg) +{ + CASE(agx_fadd_to(b, wz, agx_abs(agx_mov(b, wx)), wy), + agx_fadd_to(b, wz, agx_abs(wx), wy)); + + CASE(agx_fadd_to(b, wz, agx_neg(agx_mov(b, wx)), wy), + agx_fadd_to(b, wz, agx_neg(wx), wy)); + + CASE(agx_fadd_to(b, wz, agx_neg(agx_abs(agx_mov(b, wx))), wy), + agx_fadd_to(b, wz, agx_neg(agx_abs(wx)), wy)); +} + +TEST_F(Optimizer, IntCopyprop) +{ + CASE(agx_xor_to(b, wz, agx_mov(b, wx), wy), + agx_xor_to(b, wz, wx, wy)); +} + +TEST_F(Optimizer, IntCopypropDoesntConvert) +{ + NEGCASE({ + agx_index cvt = agx_temp(b->shader, AGX_SIZE_32); + agx_mov_to(b, cvt, hx); + agx_xor_to(b, wz, cvt, wy); + }); +}