r300: another fix for reader detection in the presence of loops
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 <pavel.ondracka@gmail.com>
Reviewed-by: Filip Gawin <filip@gawin.net>
Tested-by: Filip Gawin <filip@gawin.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19618>
diff --git a/src/gallium/drivers/r300/compiler/radeon_dataflow.c b/src/gallium/drivers/r300/compiler/radeon_dataflow.c
index ea81dc3..d761ae9 100644
--- a/src/gallium/drivers/r300/compiler/radeon_dataflow.c
+++ b/src/gallium/drivers/r300/compiler/radeon_dataflow.c
@@ -686,6 +686,7 @@
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 @@
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 @@
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 @@
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;
}
}