mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
aco: don't use uniform continues if exec might be empty
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com> Reviewed-by: Daniel Schürmann <daniel@schuermann.dev> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31143>
This commit is contained in:
parent
aa0ede751d
commit
63b0692eac
2 changed files with 56 additions and 7 deletions
|
|
@ -10249,6 +10249,14 @@ emit_loop_jump(isel_context* ctx, bool is_break)
|
|||
append_logical_end(ctx->block);
|
||||
unsigned idx = ctx->block->index;
|
||||
|
||||
/* If exec is empty inside uniform control flow in a loop, we can assume that all invocations
|
||||
* of the loop are inactive. Breaking from the loop is the right thing to do in that case.
|
||||
* We shouldn't perform a uniform continue, or else we might never reach a break.
|
||||
*/
|
||||
bool potentially_empty_exec = ctx->cf_info.exec.potentially_empty_discard ||
|
||||
ctx->cf_info.exec.potentially_empty_break ||
|
||||
ctx->cf_info.exec.potentially_empty_continue;
|
||||
|
||||
if (is_break) {
|
||||
logical_target = ctx->cf_info.parent_loop.exit;
|
||||
add_logical_edge(idx, logical_target);
|
||||
|
|
@ -10274,7 +10282,7 @@ emit_loop_jump(isel_context* ctx, bool is_break)
|
|||
add_logical_edge(idx, logical_target);
|
||||
ctx->block->kind |= block_kind_continue;
|
||||
|
||||
if (!ctx->cf_info.parent_if.is_divergent) {
|
||||
if (!ctx->cf_info.parent_if.is_divergent && !potentially_empty_exec) {
|
||||
/* uniform continue - directly jump to the loop header */
|
||||
ctx->block->kind |= block_kind_uniform;
|
||||
ctx->cf_info.has_branch = true;
|
||||
|
|
@ -10283,14 +10291,17 @@ emit_loop_jump(isel_context* ctx, bool is_break)
|
|||
return;
|
||||
}
|
||||
|
||||
/* for potential uniform breaks after this continue,
|
||||
we must ensure that they are handled correctly */
|
||||
ctx->cf_info.parent_loop.has_divergent_continue = true;
|
||||
ctx->cf_info.parent_loop.has_divergent_branch = true;
|
||||
|
||||
if (!ctx->cf_info.exec.potentially_empty_continue) {
|
||||
ctx->cf_info.exec.potentially_empty_continue = true;
|
||||
ctx->cf_info.exec.potentially_empty_continue_depth = ctx->block->loop_nest_depth;
|
||||
if (ctx->cf_info.parent_if.is_divergent) {
|
||||
/* for potential uniform breaks after this continue,
|
||||
we must ensure that they are handled correctly */
|
||||
ctx->cf_info.parent_loop.has_divergent_continue = true;
|
||||
|
||||
if (!ctx->cf_info.exec.potentially_empty_continue) {
|
||||
ctx->cf_info.exec.potentially_empty_continue = true;
|
||||
ctx->cf_info.exec.potentially_empty_continue_depth = ctx->block->loop_nest_depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1741,3 +1741,41 @@ BEGIN_TEST(isel.cf.empty_exec.repair_ssa)
|
|||
|
||||
finish_isel_test();
|
||||
END_TEST
|
||||
|
||||
/*
|
||||
* loop {
|
||||
* if (uniform) {
|
||||
* terminate_if
|
||||
* //potentially empty
|
||||
* continue
|
||||
* }
|
||||
* //potentially empty
|
||||
* break
|
||||
* }
|
||||
*/
|
||||
BEGIN_TEST(isel.cf.empty_exec.loop_uniform_continue)
|
||||
if (!setup_nir_cs(GFX11))
|
||||
return;
|
||||
|
||||
nir_push_loop(nb);
|
||||
{
|
||||
//>> BB1
|
||||
//! /* logical preds: BB0, BB2, / linear preds: BB0, BB3, / kind: uniform, loop-header, */
|
||||
|
||||
nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base = 0));
|
||||
{
|
||||
//>> BB2
|
||||
//! /* logical preds: BB1, / linear preds: BB1, / kind: continue, discard, */
|
||||
nir_terminate_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base = 1));
|
||||
nir_jump(nb, nir_jump_continue);
|
||||
}
|
||||
nir_pop_if(nb, NULL);
|
||||
|
||||
//>> BB6
|
||||
//! /* logical preds: BB5, / linear preds: BB4, BB5, / kind: uniform, break, */
|
||||
nir_jump(nb, nir_jump_break);
|
||||
}
|
||||
nir_pop_loop(nb, NULL);
|
||||
|
||||
finish_isel_test();
|
||||
END_TEST
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue