pan/midgard: Add csel invert optimization
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Sat, 28 Sep 2019 16:39:15 +0000 (12:39 -0400)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 30 Sep 2019 12:40:13 +0000 (08:40 -0400)
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 8bbf67aa4e7c3c201beefd64d48a8b56bd038572..b0b5ba0714388e8bc236815f53369928bbf9ddae 100644 (file)
@@ -654,6 +654,7 @@ void midgard_lower_invert(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_not_propagate(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_fuse_src_invert(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_fuse_dest_invert(compiler_context *ctx, midgard_block *block);
+bool midgard_opt_csel_invert(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_promote_fmov(compiler_context *ctx, midgard_block *block);
 
 #endif
index f1f8b7ecb9a362e4fb1f3a795a19595d71a6d3b7..857e6c701128b6d5548d058c6426f5b5a85a39a0 100644 (file)
@@ -2512,6 +2512,7 @@ midgard_compile_shader_nir(struct midgard_screen *screen, nir_shader *nir, midga
                         progress |= midgard_opt_not_propagate(ctx, block);
                         progress |= midgard_opt_fuse_src_invert(ctx, block);
                         progress |= midgard_opt_fuse_dest_invert(ctx, block);
+                        progress |= midgard_opt_csel_invert(ctx, block);
                 }
         } while (progress);
 
index f846bca5bf99e989078a3f6aa47a931d386a430a..3a4c455877ce535a20f2f887546a93dc24d7179d 100644 (file)
@@ -275,3 +275,28 @@ midgard_opt_fuse_src_invert(compiler_context *ctx, midgard_block *block)
 
         return progress;
 }
+
+/* Optimizes a .not away when used as the source of a conditional select:
+ *
+ * csel(a, b, c)  = { b if a, c if !a }
+ * csel(!a, b, c) = { b if !a, c if !(!a) } = { c if a, b if !a } = csel(a, c, b)
+ * csel(!a, b, c) = csel(a, c, b)
+ */
+
+bool
+midgard_opt_csel_invert(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 (!OP_IS_CSEL(ins->alu.op)) continue;
+                if (!mir_single_use(ctx, ins->src[2])) continue;
+                if (!mir_strip_inverted(ctx, ins->src[2])) continue;
+
+                mir_flip(ins);
+                progress |= true;
+        }
+
+        return progress;
+}