From 49f4f1ec229b1d20f61a955f4a509602b24107b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Fri, 21 Jan 2022 14:08:33 +0100 Subject: [PATCH] r300: fix deadcode elimination in loops with breaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Acked-by: Emma Anholt Part-of: --- .../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: