Mesa (main): r300: fix deadcode elimination in loops with breaks

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Feb 5 18:21:18 UTC 2022


Module: Mesa
Branch: main
Commit: 49f4f1ec229b1d20f61a955f4a509602b24107b1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=49f4f1ec229b1d20f61a955f4a509602b24107b1

Author: Pavel Ondračka <pavel.ondracka at gmail.com>
Date:   Fri Jan 21 14:08:33 2022 +0100

r300: fix deadcode elimination in loops with breaks

We are updating the deadcode state while walking the program backwards.
When encountering ENDLOOP, we scan the loop, mark everything in the loop
as used and than continue as usuall. We were previously trying to be
smart with the breaks. This was however not working as expected.

Instead, save the most pesimistic deadcode state from the ENDLOOP and
just restore it anytime we see a break.

This keeps the code simple and more importantly does not touch the flat
and IF(-ELSE)-ENDIF paths at all so reduces the chances of regression.
No changes with my shader-db.

Fixes piglits on RV530:
    shaders/ssa/fs-if-def-else-break.shader_test
    spec/glsl-1.10/execution/vs-loop-array-index-unroll.shader_test

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5832
Signed-off-by: Pavel Ondračka <pavel.ondracka at gmail.com>
Acked-by: Emma Anholt <emma at anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14661>

---

 .../r300/compiler/radeon_dataflow_deadcode.c       | 27 ++++++++--------------
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/src/gallium/drivers/r300/compiler/radeon_dataflow_deadcode.c b/src/gallium/drivers/r300/compiler/radeon_dataflow_deadcode.c
index 22b6d1ba58d..954271296aa 100644
--- a/src/gallium/drivers/r300/compiler/radeon_dataflow_deadcode.c
+++ b/src/gallium/drivers/r300/compiler/radeon_dataflow_deadcode.c
@@ -44,7 +44,7 @@ struct instruction_state {
 };
 
 struct loopinfo {
-	struct updatemask_state * Breaks;
+	struct updatemask_state StoreEndloop;
 	unsigned int BreakCount;
 	unsigned int BreaksReserved;
 };
@@ -88,20 +88,12 @@ static void or_updatemasks(
 	dst->Address = a->Address | b->Address;
 }
 
-static void push_break(struct deadcode_state *s)
-{
-	struct loopinfo * loop = &s->LoopStack[s->LoopStackSize - 1];
-	memory_pool_array_reserve(&s->C->Pool, struct updatemask_state,
-		loop->Breaks, loop->BreakCount, loop->BreaksReserved, 1);
-
-	memcpy(&loop->Breaks[loop->BreakCount++], &s->R, sizeof(s->R));
-}
-
 static void push_loop(struct deadcode_state * s)
 {
 	memory_pool_array_reserve(&s->C->Pool, struct loopinfo, s->LoopStack,
 			s->LoopStackSize, s->LoopStackReserved, 1);
 	memset(&s->LoopStack[s->LoopStackSize++], 0, sizeof(struct loopinfo));
+	memcpy(&s->LoopStack[s->LoopStackSize - 1].StoreEndloop, &s->R, sizeof(s->R));
 }
 
 static void push_branch(struct deadcode_state * s)
@@ -230,7 +222,9 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, void *user)
 
 		switch(opcode->Opcode){
 		/* Mark all sources in the loop body as used before doing
-		 * normal deadcode analysis.  This is probably not optimal.
+		 * normal deadcode analysis. This is probably not optimal.
+		 * Save this pessimistic deadcode state and restore it anytime
+		 * we see a break just to be extra sure.
 		 */
 		case RC_OPCODE_ENDLOOP:
 		{
@@ -268,17 +262,14 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, void *user)
 			break;
 		}
 		case RC_OPCODE_BRK:
-			push_break(&s);
-			break;
-		case RC_OPCODE_BGNLOOP:
 		{
-			unsigned int i;
 			struct loopinfo * loop = &s.LoopStack[s.LoopStackSize-1];
-			for(i = 0; i < loop->BreakCount; i++) {
-				or_updatemasks(&s.R, &s.R, &loop->Breaks[i]);
-			}
+			memcpy(&s.R, &loop->StoreEndloop, sizeof(s.R));
 			break;
 		}
+		case RC_OPCODE_BGNLOOP:
+			s.LoopStackSize--;
+			break;
 		case RC_OPCODE_CONT:
 			break;
 		case RC_OPCODE_ENDIF:



More information about the mesa-commit mailing list