}
static unsigned int loop_max_possible_iterations(struct radeon_compiler *c,
- struct loop_info * loop, unsigned int prog_inst_limit)
+ struct loop_info * loop)
{
unsigned int total_i = rc_recompute_ips(c);
unsigned int loop_i = (loop->EndLoop->IP - loop->BeginLoop->IP) - 1;
/* +1 because the program already has one iteration of the loop. */
- return 1 + ((prog_inst_limit - total_i) / loop_i);
+ return 1 + ((c->max_alu_insts - total_i) / loop_i);
}
static void unroll_loop(struct radeon_compiler * c, struct loop_info * loop,
}
}
-static int try_unroll_loop(struct radeon_compiler * c, struct loop_info * loop,
- unsigned int prog_inst_limit)
+/**
+ * If c->max_alu_inst is -1, then all eligible loops will be unrolled regardless
+ * of how many iterations they have.
+ */
+static int try_unroll_loop(struct radeon_compiler * c, struct loop_info * loop)
{
int end_loops;
int iterations;
return 0;
}
- if (iterations > loop_max_possible_iterations(c, loop,
- prog_inst_limit)) {
+ if (c->max_alu_insts > 0
+ && iterations > loop_max_possible_iterations(c, loop)) {
return 0;
}
case RC_OPCODE_SNE:
break;
default:
- rc_error(c, "%s: expected conditional",
- __FUNCTION__);
return 0;
}
loop->Cond = loop->If->Prev;
* ENDLOOP; -> ENDLOOP
*
* @param inst A pointer to a BGNLOOP instruction.
- * @return If the loop can be unrolled, a pointer to the first instruction of
- * the unrolled loop.
- * Otherwise, A pointer to the ENDLOOP instruction.
- * Null if there is an error.
+ * @return 1 for success, 0 for failure
*/
-static struct rc_instruction * transform_loop(struct emulate_loop_state * s,
- struct rc_instruction * inst,
- int prog_inst_limit)
+static int transform_loop(struct emulate_loop_state * s,
+ struct rc_instruction * inst)
{
struct loop_info * loop;
loop = &s->Loops[s->LoopCount++];
- if (!build_loop_info(s->C, loop, inst))
- return NULL;
+ if (!build_loop_info(s->C, loop, inst)) {
+ rc_error(s->C, "Failed to build loop info\n");
+ return 0;
+ }
- if(try_unroll_loop(s->C, loop, prog_inst_limit)){
- return loop->BeginLoop->Next;
+ if(try_unroll_loop(s->C, loop)){
+ return 1;
}
/* Reverse the conditional instruction */
break;
default:
rc_error(s->C, "loop->Cond is not a conditional.\n");
- return NULL;
+ return 0;
}
/* Prepare the loop to be emulated */
rc_remove_instruction(loop->Brk);
rc_remove_instruction(loop->EndIf);
rc_insert_instruction(loop->EndLoop->Prev, loop->EndIf);
- return loop->EndLoop;
+ return 1;
}
-void rc_transform_loops(struct radeon_compiler *c,
- struct emulate_loop_state * s,
- int prog_inst_limit)
+void rc_transform_loops(struct radeon_compiler *c, void *user)
{
+ struct emulate_loop_state * s = &c->loop_state;
struct rc_instruction * ptr;
memset(s, 0, sizeof(struct emulate_loop_state));
s->C = c;
- ptr = s->C->Program.Instructions.Next;
- while(ptr != &s->C->Program.Instructions) {
+ for(ptr = s->C->Program.Instructions.Next;
+ ptr != &s->C->Program.Instructions; ptr = ptr->Next) {
if(ptr->Type == RC_INSTRUCTION_NORMAL &&
ptr->U.I.Opcode == RC_OPCODE_BGNLOOP){
- ptr = transform_loop(s, ptr, prog_inst_limit);
- if(!ptr){
+ if (!transform_loop(s, ptr))
return;
- }
}
- ptr = ptr->Next;
}
}
-void rc_unroll_loops(struct radeon_compiler *c, int prog_inst_limit)
+void rc_unroll_loops(struct radeon_compiler *c, void *user)
{
struct rc_instruction * inst;
struct loop_info loop;
if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP) {
if (build_loop_info(c, &loop, inst)) {
- try_unroll_loop(c, &loop, prog_inst_limit);
+ try_unroll_loop(c, &loop);
}
}
}
}
-void rc_emulate_loops(struct emulate_loop_state *s, int prog_inst_limit)
+void rc_emulate_loops(struct radeon_compiler *c, void *user)
{
+ struct emulate_loop_state * s = &c->loop_state;
int i;
/* Iterate backwards of the list of loops so that loops that nested
* loops are unrolled first.
*/
for( i = s->LoopCount - 1; i >= 0; i-- ){
+ unsigned int iterations;
+
if(!s->Loops[i].EndLoop){
continue;
}
- unsigned int iterations = loop_max_possible_iterations(
- s->C, &s->Loops[i], prog_inst_limit);
+ iterations = loop_max_possible_iterations(s->C, &s->Loops[i]);
unroll_loop(s->C, &s->Loops[i], iterations);
}
}