diff options
author | Alyssa Rosenzweig <alyssa@collabora.com> | 2021-07-26 18:13:32 -0400 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-07-28 00:26:06 +0000 |
commit | 30f8fb82c99dfbb45542196ed60c37e47b3f5d73 (patch) | |
tree | 6d4947447439efded58f552298496df8fb6f88c6 /src | |
parent | e3554a9a3aa1e2c59a952375b326c3fdb3618cf8 (diff) |
pan/bi: Clean up and export bi_reconverge_branches
Decides when we need "branch reconvergence" (canonical term), the
logical opposite of "back-to-back execution" (non-canonical term, this
is old code in Bifrost terms). So invert the return value, rename, and
export so we can use it when packing Valhall instructions.
Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12026>
Diffstat (limited to 'src')
-rw-r--r-- | src/panfrost/bifrost/bi_schedule.c | 27 | ||||
-rw-r--r-- | src/panfrost/bifrost/bir.c | 27 | ||||
-rw-r--r-- | src/panfrost/bifrost/compiler.h | 1 |
3 files changed, 29 insertions, 26 deletions
diff --git a/src/panfrost/bifrost/bi_schedule.c b/src/panfrost/bifrost/bi_schedule.c index 6e0a9ea5e18..5b880a7c2b1 100644 --- a/src/panfrost/bifrost/bi_schedule.c +++ b/src/panfrost/bifrost/bi_schedule.c @@ -468,31 +468,6 @@ bi_update_worklist(struct bi_worklist st, unsigned idx) free(st.dependents[idx]); } -/* To work out the back-to-back flag, we need to detect branches and - * "fallthrough" branches, implied in the last clause of a block that falls - * through to another block with *multiple predecessors*. */ - -static bool -bi_back_to_back(bi_block *block) -{ - /* Last block of a program */ - if (!block->successors[0]) { - assert(!block->successors[1]); - return false; - } - - /* Multiple successors? We're branching */ - if (block->successors[1]) - return false; - - struct bi_block *succ = block->successors[0]; - assert(succ->predecessors); - unsigned count = succ->predecessors->entries; - - /* Back to back only if the successor has only a single predecessor */ - return (count == 1); -} - /* Scheduler predicates */ /* IADDC.i32 can implement IADD.u32 if no saturation or swizzling is in use */ @@ -1776,7 +1751,7 @@ bi_schedule_block(bi_context *ctx, bi_block *block) * the rest are implicitly true */ if (!list_is_empty(&block->clauses)) { bi_clause *last_clause = list_last_entry(&block->clauses, bi_clause, link); - if (!bi_back_to_back(block)) + if (bi_reconverge_branches(block)) last_clause->flow_control = BIFROST_FLOW_NBTB_UNCONDITIONAL; } diff --git a/src/panfrost/bifrost/bir.c b/src/panfrost/bifrost/bir.c index c76142689ea..7444d2e4dd0 100644 --- a/src/panfrost/bifrost/bir.c +++ b/src/panfrost/bifrost/bir.c @@ -177,3 +177,30 @@ bi_side_effects(enum bi_opcode op) unreachable("Invalid message type"); } + +/* Branch reconvergence is required when the execution mask may change + * between adjacent instructions (clauses). This occurs for conditional + * branches and for the last instruction (clause) in a block whose + * fallthrough successor has multiple predecessors. + */ + +bool +bi_reconverge_branches(bi_block *block) +{ + /* Last block of a program */ + if (!block->successors[0]) { + assert(!block->successors[1]); + return true; + } + + /* Multiple successors? We're branching */ + if (block->successors[1]) + return true; + + struct bi_block *succ = block->successors[0]; + assert(succ->predecessors); + unsigned count = succ->predecessors->entries; + + /* Reconverge if there are multiple predecessors */ + return (count != 1); +} diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index a0239ad335c..2c731ee9cae 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -871,6 +871,7 @@ bool bi_is_regfmt_16(enum bi_register_format fmt); unsigned bi_writemask(const bi_instr *ins, unsigned dest); bi_clause * bi_next_clause(bi_context *ctx, bi_block *block, bi_clause *clause); bool bi_side_effects(enum bi_opcode op); +bool bi_reconverge_branches(bi_block *block); void bi_print_instr(const bi_instr *I, FILE *fp); void bi_print_slots(bi_registers *regs, FILE *fp); |