diff options
author | Tom Stellard <tstellar@gmail.com> | 2010-08-03 15:23:23 -0700 |
---|---|---|
committer | Tom Stellard <tstellar@gmail.com> | 2010-08-03 19:11:08 -0700 |
commit | 2824d5687a19e42ba0da8fd08e80610c4469a3b3 (patch) | |
tree | 62c397d260f054fc1fd502c796963b7ecbc78605 /src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c | |
parent | 9dcc5006660037665fe98bf2d9fb966e620a038b (diff) |
r300/compiler: r500 hw support for break and continue in loops.
The BGNLOOP and ENDLOOP instructions are now being used correctly, which
makes break and continue possible. The deadcode pass has been modified to
handle breaks, and the compiler is more careful about which loops are
unrolled.
Diffstat (limited to 'src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c')
-rw-r--r-- | src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c index fbb4235c22..31566a937f 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c @@ -43,6 +43,12 @@ struct instruction_state { unsigned char SrcReg[3]; }; +struct loopinfo { + struct updatemask_state * Breaks; + unsigned int BreakCount; + unsigned int BreaksReserved; +}; + struct branchinfo { unsigned int HaveElse:1; @@ -59,6 +65,10 @@ struct deadcode_state { struct branchinfo * BranchStack; unsigned int BranchStackSize; unsigned int BranchStackReserved; + + struct loopinfo * LoopStack; + unsigned int LoopStackSize; + unsigned int LoopStackReserved; }; @@ -78,6 +88,22 @@ 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)); +} + static void push_branch(struct deadcode_state * s) { memory_pool_array_reserve(&s->C->Pool, struct branchinfo, s->BranchStack, @@ -233,11 +259,22 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f } } } + push_loop(&s); break; } - case RC_OPCODE_CONTINUE: 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]); + } + break; + } + case RC_OPCODE_CONTINUE: break; case RC_OPCODE_ENDIF: push_branch(&s); |