pan/midgard: Add class check
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 24 Jul 2019 18:33:26 +0000 (11:33 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 25 Jul 2019 13:37:22 +0000 (06:37 -0700)
This ensures the rules for accessing special register classes are
satisfied. This is asserted as a prepass should have lowered offending
uses to something satisfying these rules. Special register classes are
*not* work registers and cannot be used for RMW operations; they are
essentially 1-way pipes straight into/from fixed-function logic in the
shader cores.

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

index 2f4bdc65c35df2a6b9e22795295b35fea1ace08b..9a2203c02e32076d65f072ed6f7a504e0c911031 100644 (file)
@@ -266,7 +266,7 @@ static void
 set_class(unsigned *classes, unsigned node, unsigned class)
 {
         /* Check that we're even a node */
-        if ((node < 0) ||(node >= SSA_FIXED_MINIMUM))
+        if ((node < 0) || (node >= SSA_FIXED_MINIMUM))
                 return;
 
         /* First 4 are work, next 4 are load/store.. */
@@ -285,6 +285,26 @@ set_class(unsigned *classes, unsigned node, unsigned class)
         classes[node] |= (class << 2);
 }
 
+/* Special register classes impose special constraints on who can read their
+ * values, so check that */
+
+static bool
+check_read_class(unsigned *classes, unsigned tag, unsigned node)
+{
+        /* Non-nodes are implicitly ok */
+        if ((node < 0) || (node >= SSA_FIXED_MINIMUM))
+                return true;
+
+        unsigned current_class = classes[node] >> 2;
+
+        switch (current_class) {
+        case REG_CLASS_LDST:
+                return (tag == TAG_LOAD_STORE_4);
+        default:
+                return (tag != TAG_LOAD_STORE_4);
+        }
+}
+
 /* This routine performs the actual register allocation. It should be succeeded
  * by install_registers */
 
@@ -349,6 +369,15 @@ allocate_registers(compiler_context *ctx, bool *spilled)
                 }
         }
 
+        /* Check that the semantics of the class are respected */
+        mir_foreach_instr_global(ctx, ins) {
+                if (ins->compact_branch) continue;
+
+                /* Non-load-store cannot read load/store */
+                assert(check_read_class(found_class, ins->type, ins->ssa_args.src0));
+                assert(check_read_class(found_class, ins->type, ins->ssa_args.src1));
+        }
+
         for (unsigned i = 0; i < ctx->temp_count; ++i) {
                 unsigned class = found_class[i];
                 if (!class) continue;