pan/bi: Fuse DISCARD with conditions
authorAlyssa Rosenzweig <alyssa@collabora.com>
Tue, 3 Aug 2021 21:56:31 +0000 (17:56 -0400)
committerAlyssa Rosenzweig <alyssa@collabora.com>
Wed, 11 Aug 2021 18:59:26 +0000 (14:59 -0400)
Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12205>

src/panfrost/bifrost/ISA.xml
src/panfrost/bifrost/bi_opt_mod_props.c
src/panfrost/bifrost/bifrost_compile.c
src/panfrost/bifrost/bir.c

index f49e44f..cb407c1 100644 (file)
     </mod>
   </ins>
 
+  <ins name="+DISCARD.b32" pseudo="true" dests="0">
+    <src start="0"/>
+    <mod name="widen0" size="2">
+      <opt>none</opt>
+      <opt>h0</opt>
+      <opt>h1</opt>
+    </mod>
+  </ins>
+
 </bifrost>
index f4afdc1..44eae29 100644 (file)
@@ -105,6 +105,35 @@ bi_compose_float_index(bi_index old, bi_index repl)
         return repl;
 }
 
+/* DISCARD.b32(FCMP.f(x, y)) --> DISCARD.f(x, y) */
+
+static inline void
+bi_fuse_discard_fcmp(bi_instr *I, bi_instr *mod, unsigned arch)
+{
+        if (I->op != BI_OPCODE_DISCARD_B32) return;
+        if (mod->op != BI_OPCODE_FCMP_F32 && mod->op != BI_OPCODE_FCMP_V2F16) return;
+        if (mod->cmpf >= BI_CMPF_GTLT) return;
+
+        /* .abs and .neg modifiers allowed on Valhall DISCARD but not Bifrost */
+        bool absneg = mod->src[0].neg || mod->src[0].abs;
+        absneg     |= mod->src[1].neg || mod->src[1].abs;
+
+        if (arch <= 8 && absneg) return;
+
+        enum bi_swizzle r = I->src[0].swizzle;
+
+        /* result_type doesn't matter */
+        I->op = BI_OPCODE_DISCARD_F32;
+        I->cmpf = mod->cmpf;
+        I->src[0] = mod->src[0];
+        I->src[1] = mod->src[1];
+
+        if (mod->op == BI_OPCODE_FCMP_V2F16) {
+                I->src[0].swizzle = bi_compose_swizzle_16(r, I->src[0].swizzle);
+                I->src[1].swizzle = bi_compose_swizzle_16(r, I->src[1].swizzle);
+        }
+}
+
 void
 bi_opt_mod_prop_forward(bi_context *ctx)
 {
@@ -125,6 +154,8 @@ bi_opt_mod_prop_forward(bi_context *ctx)
 
                         unsigned size = bi_opcode_props[I->op].size;
 
+                        bi_fuse_discard_fcmp(I, mod, ctx->arch);
+
                         if (bi_is_fabsneg(mod->op, size)) {
                                 if (mod->src[0].abs && !bi_takes_fabs(ctx->arch, I, mod->src[0], s))
                                         continue;
@@ -266,6 +297,12 @@ bi_lower_opt_instruction(bi_instr *I)
                 I->src[1] = bi_negzero();
                 break;
 
+        case BI_OPCODE_DISCARD_B32:
+                I->op = BI_OPCODE_DISCARD_F32;
+                I->src[1] = bi_imm_u16(0);
+                I->cmpf = BI_CMPF_NE;
+                break;
+
         default:
                 break;
         }
index d9d005d..fca20b3 100644 (file)
@@ -1233,7 +1233,7 @@ bi_emit_intrinsic(bi_builder *b, nir_intrinsic_instr *instr)
         case nir_intrinsic_discard_if: {
                 bi_index src = bi_src_index(&instr->src[0]);
                 assert(nir_src_bit_size(instr->src[0]) == 1);
-                bi_discard_f32(b, bi_half(src, false), bi_imm_u16(0), BI_CMPF_NE);
+                bi_discard_b32(b, bi_half(src, false));
                 break;
         }
 
index 0698336..78a2965 100644 (file)
@@ -154,9 +154,17 @@ bi_next_clause(bi_context *ctx, bi_block *block, bi_clause *clause)
 bool
 bi_side_effects(enum bi_opcode op)
 {
-        if (bi_opcode_props[op].last || op == BI_OPCODE_DISCARD_F32)
+        if (bi_opcode_props[op].last)
                 return true;
 
+        switch (op) {
+        case BI_OPCODE_DISCARD_F32:
+        case BI_OPCODE_DISCARD_B32:
+                return true;
+        default:
+                break;
+        }
+
         switch (bi_opcode_props[op].message) {
         case BIFROST_MESSAGE_NONE:
         case BIFROST_MESSAGE_VARYING: