From 0889c44f18b8b4c4155b4e6c82cc6ca21c1e467a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Fri, 11 Nov 2022 10:20:38 +0100 Subject: [PATCH] r300: another fix for reader detection in the presence of loops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helps in some cases where we fail to detect that the write mask is still alive after the loop and thus fail to detect some readers. Signed-off-by: Pavel Ondračka Reviewed-by: Filip Gawin Tested-by: Filip Gawin Part-of: --- .../drivers/r300/compiler/radeon_dataflow.c | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/r300/compiler/radeon_dataflow.c b/src/gallium/drivers/r300/compiler/radeon_dataflow.c index ea81dc3e527..d761ae9a7b0 100644 --- a/src/gallium/drivers/r300/compiler/radeon_dataflow.c +++ b/src/gallium/drivers/r300/compiler/radeon_dataflow.c @@ -686,6 +686,7 @@ static void get_readers_for_single_write( struct rc_instruction * endloop = NULL; unsigned int abort_on_read_at_endloop = 0; unsigned int abort_on_read_at_break = 0; + unsigned int alive_write_mask_at_breaks = 0; struct get_readers_callback_data * d = userdata; d->ReaderData->Writer = writer; @@ -745,6 +746,7 @@ static void get_readers_for_single_write( d->ReaderData->AbortOnRead = d->AliveWriteMask; } else { struct branch_write_mask * masks = &d->BranchMasks[branch_depth]; + alive_write_mask_at_breaks |= d->AliveWriteMask; if (masks->HasElse) { /* Abort on read for components that were written in the IF * block. */ @@ -805,6 +807,10 @@ static void get_readers_for_single_write( endloop = NULL; d->ReaderData->AbortOnRead = abort_on_read_at_endloop | abort_on_read_at_break; + /* Restore the AliveWriteMask to account for all possible + * exits from the loop. */ + d->AliveWriteMask = alive_write_mask_at_breaks; + alive_write_mask_at_breaks = 0; continue; } rc_for_all_writes_mask(tmp, get_readers_write_callback, d); @@ -812,7 +818,25 @@ static void get_readers_for_single_write( if (d->ReaderData->ExitOnAbort && d->ReaderData->Abort) return; - if (branch_depth == 0 && !d->AliveWriteMask) + /* The check for !endloop in needed for the following scenario: + * + * 0 MOV TEMP[0] none.0 + * 1 BGNLOOP + * 2 IF some exit condition + * 3 BRK + * 4 ENDIF + * 5 ADD TEMP[0], TEMP[0], CONST[0] + * 6 ADD TEMP[0], TEMP[0], none.1 + * 7 ENDLOOP + * 8 MOV OUT[0] TEMP[0] + * + * When we search for the readers of instruction 6, we encounter the ENDLOOP + * and continue searching at BGNLOOP. At instruction 5 the AliveWriteMask + * becomes 0 and we would stop the search. However we still need to continue + * back to 6 from which we jump after the endloop, restore the AliveWriteMask + * according to the possible states at breaks and continue after the loop. + */ + if (branch_depth == 0 && !d->AliveWriteMask && !endloop) return; } }