diff options
author | Alyssa Rosenzweig <[email protected]> | 2019-07-24 11:33:26 -0700 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2019-07-25 06:37:22 -0700 |
commit | 5d5caf10afffa0ff2fc9076d53962ea67fadbb6b (patch) | |
tree | d3f4918a13717aec617fa6dbf04f047484a2e579 /src/panfrost | |
parent | 91195bdff176d139867fd164221ddc05adfad17e (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.c | 31 |
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; |