mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 02:58:05 +02:00
ir3: fix physical edges of predicated branches
The algorithm for adding extra physical edges works by finding edges
that jump over reconvergence points. Since predicated branches don't
introduce reconvergence points, we wouldn't add a physical edge from the
true block to the false block. However, this physical edge is still
needed as control flow does fall though here. This patch fixes this by
manually adding the physical edge so that we don't need to insert a
reconvergence point for it.
Signed-off-by: Job Noorman <jnoorman@igalia.com>
Fixes: 39088571f0 ("ir3: add support for predication")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31733>
This commit is contained in:
parent
72871d8330
commit
19c560da04
1 changed files with 35 additions and 0 deletions
|
|
@ -154,6 +154,41 @@ ir3_calc_reconvergence(struct ir3_shader_variant *so)
|
|||
|
||||
uinterval_tree_insert(&backward_edges, &edges[edge++].node);
|
||||
}
|
||||
} else {
|
||||
struct ir3_instruction *terminator =
|
||||
ir3_block_get_terminator(block);
|
||||
|
||||
/* We don't want to mark targets of predicated branches as
|
||||
* reconvergence points below because they don't need the
|
||||
* branchstack:
|
||||
* |-- i --|
|
||||
* | ... |
|
||||
* | predt |
|
||||
* |-------|
|
||||
* succ0 / \ succ1
|
||||
* |-- i+1 --| |-- i+2 --|
|
||||
* | tblock | | fblock |
|
||||
* | predf | | jump |
|
||||
* |---------| |---------|
|
||||
* succ0 \ / succ0
|
||||
* |-- j --|
|
||||
* | ... |
|
||||
* |-------|
|
||||
* Here, neither block i+2 nor block j need (jp). However, block i+1
|
||||
* still needs a physical edge to block i+2 (control flow will fall
|
||||
* through here) but the code below won't add it unless block i+2 is
|
||||
* a reconvergence point. Therefore, we add it manually here.
|
||||
*
|
||||
* Note: we are here because the current block has only one
|
||||
* successor which means that, if there is a predicated terminator,
|
||||
* block will be block i+1 in the diagram above.
|
||||
*/
|
||||
if (terminator && (terminator->opc == OPC_PREDT ||
|
||||
terminator->opc == OPC_PREDF)) {
|
||||
struct ir3_block *next =
|
||||
list_entry(block->node.next, struct ir3_block, node);
|
||||
ir3_block_link_physical(block, next);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue