OSDN Git Service

pan/midgard: Fuse invert into bitwise ops
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 26 Jul 2019 20:08:54 +0000 (13:08 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 2 Aug 2019 16:57:15 +0000 (09:57 -0700)
We use the new invert flag to produce ops like inand.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/panfrost/midgard/compiler.h
src/panfrost/midgard/midgard_compile.c
src/panfrost/midgard/midgard_opt_invert.c

index f428db3..b5231f3 100644 (file)
@@ -576,5 +576,6 @@ bool midgard_opt_dead_move_eliminate(compiler_context *ctx, midgard_block *block
 void midgard_opt_post_move_eliminate(compiler_context *ctx, midgard_block *block, struct ra_graph *g);
 
 void midgard_lower_invert(compiler_context *ctx, midgard_block *block);
+bool midgard_opt_fuse_dest_invert(compiler_context *ctx, midgard_block *block);
 
 #endif
index a35b43f..f0b3dde 100644 (file)
@@ -2357,6 +2357,7 @@ midgard_compile_shader_nir(struct midgard_screen *screen, nir_shader *nir, midga
                         progress |= midgard_opt_dead_code_eliminate(ctx, block);
                         progress |= midgard_opt_combine_projection(ctx, block);
                         progress |= midgard_opt_varying_projection(ctx, block);
+                        progress |= midgard_opt_fuse_dest_invert(ctx, block);
                 }
         } while (progress);
 
index 1e6c5b3..aab64a3 100644 (file)
@@ -62,3 +62,58 @@ midgard_lower_invert(compiler_context *ctx, midgard_block *block)
                 mir_insert_instruction_before(mir_next_op(ins), not);
         }
 }
+
+/* With that lowering out of the way, we can focus on more interesting
+ * optimizations. One easy one is fusing inverts into bitwise operations:
+ *
+ * ~iand = inand
+ * ~ior  = inor
+ * ~ixor = inxor
+ */
+
+static bool
+mir_is_bitwise(midgard_instruction *ins)
+{
+        switch (ins->alu.op) {
+        case midgard_alu_op_iand:
+        case midgard_alu_op_ior:
+        case midgard_alu_op_ixor:
+                return true;
+        default:
+                return false;
+        }
+}
+
+static midgard_alu_op
+mir_invert_op(midgard_alu_op op)
+{
+        switch (op) {
+        case midgard_alu_op_iand:
+                return midgard_alu_op_inand;
+        case midgard_alu_op_ior:
+                return midgard_alu_op_inor;
+        case midgard_alu_op_ixor:
+                return midgard_alu_op_inxor;
+        default:
+                unreachable("Op not invertible");
+        }
+}
+
+bool
+midgard_opt_fuse_dest_invert(compiler_context *ctx, midgard_block *block)
+{
+        bool progress = false;
+
+        mir_foreach_instr_in_block_safe(block, ins) {
+                /* Search for inverted bitwise */
+                if (ins->type != TAG_ALU_4) continue;
+                if (!mir_is_bitwise(ins)) continue;
+                if (!ins->invert) continue;
+
+                ins->alu.op = mir_invert_op(ins->alu.op);
+                ins->invert = false;
+                progress |= true;
+        }
+
+        return progress;
+}