summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2010-08-22 03:29:54 +0200
committerMarek Olšák <maraeo@gmail.com>2010-08-25 02:44:28 +0200
commit6c88f84bddf4b61f8306c5e0eb48642cb636bd58 (patch)
tree74c500dc1ad6c08d08654815aca8964396134910
parent3aee8c3b1d10f8e8978c1b902aff4347684d4e79 (diff)
r300/compiler: handle indexable temporaries correctly in deadcode elimination
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c31
1 files changed, 30 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 faf531b412..acdb371de9 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
@@ -157,8 +157,12 @@ static void update_instruction(struct deadcode_state * s, struct rc_instruction
unsigned char * pused = get_used_ptr(s, inst->U.I.DstReg.File, inst->U.I.DstReg.Index);
if (pused) {
usedmask = *pused & inst->U.I.DstReg.WriteMask;
- *pused &= ~usedmask;
+ if (!inst->U.I.DstReg.RelAddr)
+ *pused &= ~usedmask;
}
+
+ if (inst->U.I.DstReg.RelAddr)
+ mark_used(s, RC_FILE_ADDRESS, 0, RC_MASK_X);
}
insts->WriteMask |= usedmask;
@@ -213,6 +217,7 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
{
struct deadcode_state s;
unsigned int nr_instructions;
+ unsigned has_temp_reladdr_src = 0;
memset(&s, 0, sizeof(s));
s.C = c;
@@ -300,6 +305,30 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name);
}
}
+
+ if (!has_temp_reladdr_src) {
+ for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
+ if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY &&
+ inst->U.I.SrcReg[i].RelAddr) {
+ /* If there is a register read from a temporary file with relative addressing,
+ * mark all preceding written registers as used. */
+ for (struct rc_instruction *ptr = inst->Prev;
+ ptr != &c->Program.Instructions;
+ ptr = ptr->Prev) {
+ if (opcode->HasDstReg &&
+ ptr->U.I.DstReg.File == RC_FILE_TEMPORARY &&
+ ptr->U.I.DstReg.WriteMask) {
+ mark_used(&s,
+ ptr->U.I.DstReg.File,
+ ptr->U.I.DstReg.Index,
+ ptr->U.I.DstReg.WriteMask);
+ }
+ }
+
+ has_temp_reladdr_src = 1;
+ }
+ }
+ }
}
update_instruction(&s, inst);