summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300
diff options
context:
space:
mode:
authorTom Stellard <tstellar@gmail.com>2010-11-13 16:57:06 -0800
committerTom Stellard <tstellar@gmail.com>2010-11-21 18:48:31 -0800
commite2301b45c288cdbd4e763dfbc698d709045f2df5 (patch)
treec828d349aaddfc08d22c67a787f469bb57ac0446 /src/mesa/drivers/dri/r300
parent412803b5cd64a5771835366b38b398a2ed8732d8 (diff)
r300/compiler: Fix register allocator's handling of loops
NOTE: This is a candidate for the 7.9 branch.
Diffstat (limited to 'src/mesa/drivers/dri/r300')
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
index 91524f5ec6..3f880c88fa 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
@@ -66,10 +66,13 @@ struct regalloc_state {
struct hardware_register * HwTemporary;
unsigned int NumHwTemporaries;
/**
- * If an instruction is inside of a loop, end_loop will be the
- * IP of the ENDLOOP instruction, otherwise end_loop will be 0
+ * If an instruction is inside of a loop, EndLoop will be the
+ * IP of the ENDLOOP instruction, and BeginLoop will be the IP
+ * of the BGNLOOP instruction. Otherwise, EndLoop and BeginLoop
+ * will be -1.
*/
- int end_loop;
+ int EndLoop;
+ int BeginLoop;
};
static void print_live_intervals(struct live_intervals * src)
@@ -180,11 +183,13 @@ static void scan_callback(void * data, struct rc_instruction * inst,
reg->Used = 1;
if (file == RC_FILE_INPUT)
reg->Live.Start = -1;
+ else if (s->BeginLoop >= 0)
+ reg->Live.Start = s->BeginLoop;
else
reg->Live.Start = inst->IP;
reg->Live.End = inst->IP;
- } else if (s->end_loop)
- reg->Live.End = s->end_loop;
+ } else if (s->EndLoop >= 0)
+ reg->Live.End = s->EndLoop;
else if (inst->IP > reg->Live.End)
reg->Live.End = inst->IP;
}
@@ -195,6 +200,8 @@ static void compute_live_intervals(struct radeon_compiler *c,
memset(s, 0, sizeof(*s));
s->C = c;
s->NumHwTemporaries = c->max_temp_regs;
+ s->BeginLoop = -1;
+ s->EndLoop = -1;
s->HwTemporary =
memory_pool_malloc(&c->Pool,
s->NumHwTemporaries * sizeof(struct hardware_register));
@@ -207,8 +214,10 @@ static void compute_live_intervals(struct radeon_compiler *c,
inst = inst->Next) {
/* For all instructions inside of a loop, the ENDLOOP
- * instruction is used as the end of the live interval. */
- if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && !s->end_loop) {
+ * instruction is used as the end of the live interval and
+ * the BGNLOOP instruction is used as the beginning. */
+ if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && s->EndLoop < 0) {
+ s->BeginLoop = inst->IP;
int loops = 1;
struct rc_instruction * tmp;
for(tmp = inst->Next;
@@ -219,15 +228,17 @@ static void compute_live_intervals(struct radeon_compiler *c,
} else if (tmp->U.I.Opcode
== RC_OPCODE_ENDLOOP) {
if(!--loops) {
- s->end_loop = tmp->IP;
+ s->EndLoop = tmp->IP;
break;
}
}
}
}
- if (inst->IP == s->end_loop)
- s->end_loop = 0;
+ if (inst->IP == s->EndLoop) {
+ s->EndLoop = -1;
+ s->BeginLoop = -1;
+ }
rc_for_all_reads_mask(inst, scan_callback, s);
rc_for_all_writes_mask(inst, scan_callback, s);