summaryrefslogtreecommitdiffstats
path: root/src/panfrost
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-07-24 11:33:26 -0700
committerAlyssa Rosenzweig <[email protected]>2019-07-25 06:37:22 -0700
commit5d5caf10afffa0ff2fc9076d53962ea67fadbb6b (patch)
treed3f4918a13717aec617fa6dbf04f047484a2e579 /src/panfrost
parent91195bdff176d139867fd164221ddc05adfad17e (diff)
pan/midgard: Add class check
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 <[email protected]>
Diffstat (limited to 'src/panfrost')
-rw-r--r--src/panfrost/midgard/midgard_ra.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c
index 2f4bdc65c35..9a2203c02e3 100644
--- a/src/panfrost/midgard/midgard_ra.c
+++ b/src/panfrost/midgard/midgard_ra.c
@@ -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;