summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
diff options
context:
space:
mode:
authorTom Stellard <tstellar@gmail.com>2010-06-11 23:09:36 -0700
committerMarek Olšák <maraeo@gmail.com>2010-07-03 04:27:09 +0200
commit697d666d7860b3bdced32ca7fde9dea38f67da15 (patch)
tree3969cfde48c0bae7f0d763fe4080195012c320da /src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
parent91c37599f621a0ec498c0f0add14f16470ca852b (diff)
r300/compiler: Handle loops in deadcode analysis.
This also allows us to split the loop emulation into two phases. A tranformation phase which either unrolls loops or prepares them to be emulated, and the emulation phase which unrolls remaining loops until the instruction limit is reached. The second phase is completed after the deadcode analysis in order to get a more accurate count of the number of instructions in the body of loops.
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.c75
1 files changed, 52 insertions, 23 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 e3c2c83c0c..f8bced2532 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
@@ -202,32 +202,61 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
inst = inst->Prev) {
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
- if (opcode->IsFlowControl) {
- if (opcode->Opcode == RC_OPCODE_ENDIF) {
- push_branch(&s);
- } else {
- if (s.BranchStackSize) {
- struct branchinfo * branch = &s.BranchStack[s.BranchStackSize-1];
-
- if (opcode->Opcode == RC_OPCODE_IF) {
- or_updatemasks(&s.R,
- &s.R,
- branch->HaveElse ? &branch->StoreElse : &branch->StoreEndif);
-
- s.BranchStackSize--;
- } else if (opcode->Opcode == RC_OPCODE_ELSE) {
- if (branch->HaveElse) {
- rc_error(c, "%s: Multiple ELSE for one IF/ENDIF\n", __FUNCTION__);
- } else {
- memcpy(&branch->StoreElse, &s.R, sizeof(s.R));
- memcpy(&s.R, &branch->StoreEndif, sizeof(s.R));
- branch->HaveElse = 1;
- }
+ switch(opcode->Opcode){
+ /* Mark all sources in the loop body as used before doing
+ * normal deadcode analysis. This is probably not optimal.
+ */
+ case RC_OPCODE_ENDLOOP:
+ {
+ int endloops = 1;
+ struct rc_instruction *ptr;
+ for(ptr = inst->Prev; endloops > 0; ptr = ptr->Prev){
+ opcode = rc_get_opcode_info(ptr->U.I.Opcode);
+ if(ptr->U.I.Opcode == RC_OPCODE_BGNLOOP){
+ endloops--;
+ continue;
+ }
+ if(ptr->U.I.Opcode == RC_OPCODE_ENDLOOP){
+ endloops++;
+ continue;
+ }
+ if(opcode->HasDstReg){
+ int src = 0;
+ unsigned int srcmasks[3];
+ rc_compute_sources_for_writemask(ptr,
+ ptr->U.I.DstReg.WriteMask, srcmasks);
+ for(src=0; src < opcode->NumSrcRegs; src++){
+ mark_used(&s,
+ ptr->U.I.SrcReg[src].File,
+ ptr->U.I.SrcReg[src].Index,
+ srcmasks[src]);
+ }
+ }
+ }
+ break;
+ }
+ case RC_OPCODE_ENDIF:
+ push_branch(&s);
+ break;
+ default:
+ if (opcode->IsFlowControl && s.BranchStackSize) {
+ struct branchinfo * branch = &s.BranchStack[s.BranchStackSize-1];
+ if (opcode->Opcode == RC_OPCODE_IF) {
+ or_updatemasks(&s.R,
+ &s.R,
+ branch->HaveElse ? &branch->StoreElse : &branch->StoreEndif);
+
+ s.BranchStackSize--;
+ } else if (opcode->Opcode == RC_OPCODE_ELSE) {
+ if (branch->HaveElse) {
+ rc_error(c, "%s: Multiple ELSE for one IF/ENDIF\n", __FUNCTION__);
} else {
- rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name);
+ memcpy(&branch->StoreElse, &s.R, sizeof(s.R));
+ memcpy(&s.R, &branch->StoreEndif, sizeof(s.R));
+ branch->HaveElse = 1;
}
} else {
- rc_error(c, "%s: Unexpected control flow instruction\n", __FUNCTION__);
+ rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name);
}
}
}