summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@gmail.com>2011-09-15 18:24:55 -0700
committerTom Stellard <tstellar@gmail.com>2011-09-16 17:19:56 -0700
commit96620d2275894d1e021d403c0e40007c61269563 (patch)
treee87ad5ba4e2592db6400305f8878df7de9d083bf
parent79b162ba45be545f9d230dfda489916ab4ceb942 (diff)
r300/compiler: Don't unroll loops that conditionally increment the counter
-rw-r--r--src/gallium/drivers/r300/compiler/radeon_emulate_loops.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/gallium/drivers/r300/compiler/radeon_emulate_loops.c b/src/gallium/drivers/r300/compiler/radeon_emulate_loops.c
index 205eecd1129..8c46db08093 100644
--- a/src/gallium/drivers/r300/compiler/radeon_emulate_loops.c
+++ b/src/gallium/drivers/r300/compiler/radeon_emulate_loops.c
@@ -51,6 +51,7 @@ struct count_inst {
rc_swizzle Swz;
float Amount;
int Unknown;
+ unsigned BranchDepth;
};
static float get_constant_value(struct radeon_compiler * c,
@@ -141,6 +142,14 @@ static void get_incr_amount(void * data, struct rc_instruction * inst,
(1 << GET_SWZ(count_inst->Swz,0) != mask)){
return;
}
+
+ /* XXX: Give up if the counter is modified within an IF block. We
+ * could handle this case with better analysis. */
+ if (count_inst->BranchDepth > 0) {
+ count_inst->Unknown = 1;
+ return;
+ }
+
/* Find the index of the counter register. */
opcode = rc_get_opcode_info(inst->U.I.Opcode);
if(opcode->NumSrcRegs != 2){
@@ -236,6 +245,7 @@ static int try_unroll_loop(struct radeon_compiler * c, struct loop_info * loop)
count_inst.Swz = counter->Swizzle;
count_inst.Amount = 0.0f;
count_inst.Unknown = 0;
+ count_inst.BranchDepth = 0;
end_loops = 1;
for(inst = loop->BeginLoop->Next; end_loops > 0; inst = inst->Next){
switch(inst->U.I.Opcode){
@@ -258,9 +268,11 @@ static int try_unroll_loop(struct radeon_compiler * c, struct loop_info * loop)
return 0;
}
break;
- /* XXX Check if the counter is modified within an if statement.
- */
case RC_OPCODE_IF:
+ count_inst.BranchDepth++;
+ break;
+ case RC_OPCODE_ENDIF:
+ count_inst.BranchDepth--;
break;
default:
rc_for_all_writes_mask(inst, get_incr_amount, &count_inst);