summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Stellard <tstellar@gmail.com>2010-08-11 09:24:07 -0700
committerTom Stellard <tstellar@gmail.com>2010-08-11 11:39:57 -0700
commit953e39c61d051feb9f4f25f8390045c18f211d2a (patch)
tree48407ea69e2c4780c184ce18196342f064ac5443 /src
parent481b65abaedb271d0da24c75b8c60f7bcf6d8ce9 (diff)
r300/compiler: Handle loops in the register allocator.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c38
1 files changed, 34 insertions, 4 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 8a912da461..ce72cd97ab 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
@@ -65,6 +65,11 @@ 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
+ */
+ int end_loop;
};
static void print_live_intervals(struct live_intervals * src)
@@ -178,10 +183,10 @@ static void scan_callback(void * data, struct rc_instruction * inst,
else
reg->Live.Start = inst->IP;
reg->Live.End = inst->IP;
- } else {
- if (inst->IP > reg->Live.End)
- reg->Live.End = inst->IP;
- }
+ } else if (s->end_loop)
+ reg->Live.End = s->end_loop;
+ else if (inst->IP > reg->Live.End)
+ reg->Live.End = inst->IP;
}
static void compute_live_intervals(struct regalloc_state * s)
@@ -191,6 +196,31 @@ static void compute_live_intervals(struct regalloc_state * s)
for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
inst != &s->C->Program.Instructions;
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) {
+ int loops = 1;
+ struct rc_instruction * tmp;
+ for(tmp = inst->Next;
+ tmp != &s->C->Program.Instructions;
+ tmp = tmp->Next) {
+ if (tmp->U.I.Opcode == RC_OPCODE_BGNLOOP) {
+ loops++;
+ break;
+ } else if (tmp->U.I.Opcode
+ == RC_OPCODE_ENDLOOP) {
+ if(!--loops) {
+ s->end_loop = tmp->IP;
+ break;
+ }
+ }
+ }
+ }
+
+ if (inst->IP == s->end_loop)
+ s->end_loop = 0;
+
rc_for_all_reads_mask(inst, scan_callback, s);
rc_for_all_writes_mask(inst, scan_callback, s);
}