summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-05-23 03:01:32 +0000
committerAlyssa Rosenzweig <[email protected]>2019-06-04 20:14:50 +0000
commit4a03d378270cdacadb5e519378f2f26f4bed06c0 (patch)
treebbe14680be373f71a1945ffde99a4475895f2e5e /src/gallium
parent5da0a33fab0b3cc6ea03c102bd1e156904d983e5 (diff)
panfrost/midgard: .pos propagation
A previous optimization converts fmax(x, 0.0) instructions to fmov.pos. This pass then propagates the .pos from the move up to the source instruction (when possible). From there, copy propagation will eliminate the move. In the future, we might prefer to do this in common NIR code like we do for saturate, as Bifrost can also benefit. Signed-off-by: Alyssa Rosenzweig <[email protected]> Reviewed-by: Ryan Houdek <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/panfrost/midgard/midgard_compile.c80
1 files changed, 72 insertions, 8 deletions
diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
index c519193a56a..0f3331d923b 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c
+++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
@@ -1737,6 +1737,18 @@ mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask)
}
static bool
+mir_nontrivial_source2_mod(midgard_instruction *ins)
+{
+ unsigned mask = squeeze_writemask(ins->alu.mask);
+ bool is_int = midgard_is_integer_op(ins->alu.op);
+
+ midgard_vector_alu_src src2 =
+ vector_alu_from_unsigned(ins->alu.src2);
+
+ return mir_nontrivial_mod(src2, is_int, mask);
+}
+
+static bool
midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
{
bool progress = false;
@@ -1759,14 +1771,7 @@ midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
if (ins->ssa_args.inline_constant) continue;
if (ins->has_constants) continue;
- /* Also, if the move has side effects, we're helpless */
-
- midgard_vector_alu_src src =
- vector_alu_from_unsigned(ins->alu.src2);
- unsigned mask = squeeze_writemask(ins->alu.mask);
- bool is_int = midgard_is_integer_op(ins->alu.op);
-
- if (mir_nontrivial_mod(src, is_int, mask)) continue;
+ if (mir_nontrivial_source2_mod(ins)) continue;
if (ins->alu.outmod != midgard_outmod_none) continue;
/* We're clear -- rewrite */
@@ -1778,6 +1783,64 @@ midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
return progress;
}
+/* fmov.pos is an idiom for fpos. Propoagate the .pos up to the source, so then
+ * the move can be propagated away entirely */
+
+static bool
+mir_compose_outmod(midgard_outmod *outmod, midgard_outmod comp)
+{
+ /* Nothing to do */
+ if (comp == midgard_outmod_none)
+ return true;
+
+ if (*outmod == midgard_outmod_none) {
+ *outmod = comp;
+ return true;
+ }
+
+ /* TODO: Compose rules */
+ return false;
+}
+
+static bool
+midgard_opt_pos_propagate(compiler_context *ctx, midgard_block *block)
+{
+ bool progress = false;
+
+ mir_foreach_instr_in_block_safe(block, ins) {
+ if (ins->type != TAG_ALU_4) continue;
+ if (ins->alu.op != midgard_alu_op_fmov) continue;
+ if (ins->alu.outmod != midgard_outmod_pos) continue;
+
+ /* TODO: Registers? */
+ unsigned src = ins->ssa_args.src1;
+ if (src >= ctx->func->impl->ssa_alloc) continue;
+
+ /* There might be a source modifier, too */
+ if (mir_nontrivial_source2_mod(ins)) continue;
+
+ /* Backpropagate the modifier */
+ mir_foreach_instr_in_block_from_rev(block, v, mir_prev_op(ins)) {
+ if (v->type != TAG_ALU_4) continue;
+ if (v->ssa_args.dest != src) continue;
+
+ midgard_outmod temp = v->alu.outmod;
+ progress |= mir_compose_outmod(&temp, ins->alu.outmod);
+
+ /* Throw in the towel.. */
+ if (!progress) break;
+
+ /* Otherwise, transfer the modifier */
+ v->alu.outmod = temp;
+ ins->alu.outmod = midgard_outmod_none;
+
+ break;
+ }
+ }
+
+ return progress;
+}
+
static bool
midgard_opt_copy_prop_tex(compiler_context *ctx, midgard_block *block)
{
@@ -2375,6 +2438,7 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl
progress = false;
mir_foreach_block(ctx, block) {
+ progress |= midgard_opt_pos_propagate(ctx, block);
progress |= midgard_opt_copy_prop(ctx, block);
progress |= midgard_opt_copy_prop_tex(ctx, block);
progress |= midgard_opt_dead_code_eliminate(ctx, block);