pan/midgard: Flip conditionals
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 26 Jul 2019 21:25:25 +0000 (14:25 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 2 Aug 2019 16:57:15 +0000 (09:57 -0700)
We would like to flip ops to have a constant in the second place to
enable inlining of the constant.

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

index c4a50cbaee09306e0a0b85e6b10a94c4da1d0172..23a056078477116a60284f205d56f8c44492bc3c 100644 (file)
@@ -1789,6 +1789,41 @@ inline_alu_constants(compiler_context *ctx)
         }
 }
 
+/* Being a little silly with the names, but returns the op that is the bitwise
+ * inverse of the op with the argument switched. I.e. (f and g are
+ * contrapositives):
+ *
+ * f(a, b) = ~g(b, a)
+ *
+ * Corollary: if g is the contrapositve of f, f is the contrapositive of g:
+ *
+ *      f(a, b) = ~g(b, a)
+ *      ~f(a, b) = g(b, a)
+ *      ~f(a, b) = ~h(a, b) where h is the contrapositive of g
+ *      f(a, b) = h(a, b)
+ *
+ * Thus we define this function in pairs.
+ */
+
+static inline midgard_alu_op
+mir_contrapositive(midgard_alu_op op)
+{
+        switch (op) {
+        case midgard_alu_op_flt:
+                return midgard_alu_op_fle;
+        case midgard_alu_op_fle:
+                return midgard_alu_op_flt;
+
+        case midgard_alu_op_ilt:
+                return midgard_alu_op_ile;
+        case midgard_alu_op_ile:
+                return midgard_alu_op_ilt;
+
+        default:
+                unreachable("No known contrapositive");
+        }
+}
+
 /* Midgard supports two types of constants, embedded constants (128-bit) and
  * inline constants (16-bit). Sometimes, especially with scalar ops, embedded
  * constants can be demoted to inline constants, for space savings and
@@ -1819,13 +1854,19 @@ embedded_to_inline_constant(compiler_context *ctx)
                 int op = ins->alu.op;
 
                 if (ins->ssa_args.src0 == SSA_FIXED_REGISTER(REGISTER_CONSTANT)) {
+                        bool flip = alu_opcode_props[op].props & OP_COMMUTES;
+
                         switch (op) {
-                        /* These ops require an operational change to flip
-                         * their arguments TODO */
+                        /* Conditionals can be inverted */
                         case midgard_alu_op_flt:
-                        case midgard_alu_op_fle:
                         case midgard_alu_op_ilt:
+                        case midgard_alu_op_fle:
                         case midgard_alu_op_ile:
+                                ins->alu.op = mir_contrapositive(ins->alu.op);
+                                ins->invert = true;
+                                flip = true;
+                                break;
+
                         case midgard_alu_op_fcsel:
                         case midgard_alu_op_icsel:
                                 DBG("Missed non-commutative flip (%s)\n", alu_opcode_props[op].name);
@@ -1833,7 +1874,7 @@ embedded_to_inline_constant(compiler_context *ctx)
                                 break;
                         }
 
-                        if (alu_opcode_props[op].props & OP_COMMUTES) {
+                        if (flip) {
                                 /* Flip the SSA numbers */
                                 ins->ssa_args.src0 = ins->ssa_args.src1;
                                 ins->ssa_args.src1 = SSA_FIXED_REGISTER(REGISTER_CONSTANT);