[Mesa-dev] [RFC PATCH 2/2] panfrost/midgard: Ignore imov/fmov distinction

Alyssa Rosenzweig alyssa at rosenzweig.io
Mon May 13 03:48:01 UTC 2019


We use nir_gather_ssa_types, rather than the instruction name, to decide
how moves should be compiled. This is important since the imov/fmov
never mapped to what Midgard needed to begin with. This should allow
Jason's imov/fmov merger to proceed without regressing Panfrost, since
this is one less buggy behaviour we rely on.

A great deal of future work is required for handling registers, which
likely accounts for some regressions in dEQP.

Signed-off-by: Alyssa Rosenzweig <alyssa at rosenzweig.io>
Cc: Jason Ekstrand <jason at jlekstrand.net>
---
 .../panfrost/midgard/midgard_compile.c        | 81 ++++++++++++-------
 1 file changed, 53 insertions(+), 28 deletions(-)

diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
index 4a26ba769b2..b0985f55635 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c
+++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
@@ -511,6 +511,10 @@ typedef struct compiler_context {
         unsigned sysvals[MAX_SYSVAL_COUNT];
         unsigned sysval_count;
         struct hash_table_u64 *sysval_to_id;
+
+        /* Mapping for int/float words, filled out */
+        BITSET_WORD *float_types;
+        BITSET_WORD *int_types;
 } compiler_context;
 
 /* Append instruction to end of current block */
@@ -1153,10 +1157,41 @@ emit_indirect_offset(compiler_context *ctx, nir_src *src)
         emit_mir_instruction(ctx, ins);
 }
 
+static bool
+is_probably_int(compiler_context *ctx, unsigned ssa_index)
+{
+        /* TODO: Extend to registers XXX... assume float for now since that's
+         * slightly safer for reasons we don't totally get.. */
+
+        if (ssa_index >= ctx->func->impl->ssa_alloc)
+                return false;
+
+        bool is_float = BITSET_TEST(ctx->float_types, ssa_index);
+        bool is_int = BITSET_TEST(ctx->int_types, ssa_index);
+
+        if (is_float && !is_int)
+                return false;
+
+        if (is_int && !is_float)
+                return true;
+
+        /* TODO: Other cases.. if we're not sure but it is SSA, try int... this
+         * is all kinda arbitrary right now */
+        return true;
+}
+
 #define ALU_CASE(nir, _op) \
 	case nir_op_##nir: \
 		op = midgard_alu_op_##_op; \
 		break;
+
+#define ALU_CASE_IF(nir, _fop, _iop) \
+        case nir_op_##nir: \
+                op = is_probably_int(ctx, dest) \
+                        ? midgard_alu_op_##_iop : \
+                          midgard_alu_op_##_fop; \
+                break;
+
 static bool
 nir_is_fzero_constant(nir_src src)
 {
@@ -1198,7 +1233,6 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
                 ALU_CASE(imax, imax);
                 ALU_CASE(umin, umin);
                 ALU_CASE(umax, umax);
-                ALU_CASE(fmov, fmov);
                 ALU_CASE(ffloor, ffloor);
                 ALU_CASE(fround_even, froundeven);
                 ALU_CASE(ftrunc, ftrunc);
@@ -1209,7 +1243,10 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
                 ALU_CASE(isub, isub);
                 ALU_CASE(imul, imul);
                 ALU_CASE(iabs, iabs);
-                ALU_CASE(imov, imov);
+
+                /* NIR is typeless here */
+                ALU_CASE_IF(imov, fmov, imov);
+                ALU_CASE_IF(fmov, fmov, imov);
 
                 ALU_CASE(feq32, feq);
                 ALU_CASE(fne32, fne);
@@ -3361,31 +3398,6 @@ midgard_opt_copy_prop_tex(compiler_context *ctx, midgard_block *block)
         return progress;
 }
 
-/* We don't really understand the imov/fmov split, so always use fmov (but let
- * it be imov in the IR so we don't do unsafe floating point "optimizations"
- * and break things */
-
-static void
-midgard_imov_workaround(compiler_context *ctx, midgard_block *block)
-{
-        mir_foreach_instr_in_block_safe(block, ins) {
-                if (ins->type != TAG_ALU_4) continue;
-                if (ins->alu.op != midgard_alu_op_imov) continue;
-
-                ins->alu.op = midgard_alu_op_fmov;
-                ins->alu.outmod = midgard_outmod_none;
-
-                /* Remove flags that don't make sense */
-
-                midgard_vector_alu_src s =
-                        vector_alu_from_unsigned(ins->alu.src2);
-
-                s.mod = 0;
-
-                ins->alu.src2 = vector_alu_srco_unsigned(s);
-        }
-}
-
 /* The following passes reorder MIR instructions to enable better scheduling */
 
 static void
@@ -3637,7 +3649,6 @@ emit_block(compiler_context *ctx, nir_block *block)
 
         midgard_emit_store(ctx, this_block);
         midgard_pair_load_store(ctx, this_block);
-        midgard_imov_workaround(ctx, this_block);
 
         /* Append fragment shader epilogue (value writeout) */
         if (ctx->stage == MESA_SHADER_FRAGMENT) {
@@ -3919,9 +3930,23 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl
                 ctx->block_count = 0;
                 ctx->func = func;
 
+                /* Certain instructions are typeless in NIR but int/float
+                 * typed in Midgard, so we need to gather types
+                 * per-function */
+
+                ctx->float_types = calloc(BITSET_WORDS(func->impl->ssa_alloc), sizeof(BITSET_WORD));
+                ctx->int_types = calloc(BITSET_WORDS(func->impl->ssa_alloc), sizeof(BITSET_WORD));
+                nir_gather_ssa_types(func->impl, ctx->float_types, ctx->int_types);
+
+                /* Start the block-by-block emit */
+
                 emit_cf_list(ctx, &func->impl->body);
                 emit_block(ctx, func->impl->end_block);
 
+                /* Types are per-function, so cleanup */
+                free(ctx->float_types);
+                free(ctx->int_types);
+
                 break; /* TODO: Multi-function shaders */
         }
 
-- 
2.20.1



More information about the mesa-dev mailing list