mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
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@gmail.com>
Acked-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14661>
This commit is contained in:
parent
9da3d714b8
commit
49f4f1ec22
1 changed files with 9 additions and 18 deletions
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue