diff --git a/src/gallium/drivers/r300/compiler/radeon_compiler.c b/src/gallium/drivers/r300/compiler/radeon_compiler.c index 751e3622b20..ab36513e0ae 100644 --- a/src/gallium/drivers/r300/compiler/radeon_compiler.c +++ b/src/gallium/drivers/r300/compiler/radeon_compiler.c @@ -45,6 +45,7 @@ void rc_init(struct radeon_compiler * c, const struct rc_regalloc_state *rs) c->Program.Instructions.Next = &c->Program.Instructions; c->Program.Instructions.U.I.Opcode = RC_OPCODE_ILLEGAL_OPCODE; c->regalloc_state = rs; + c->max_temp_index = -1; } void rc_destroy(struct radeon_compiler * c) diff --git a/src/gallium/drivers/r300/compiler/radeon_compiler.h b/src/gallium/drivers/r300/compiler/radeon_compiler.h index 682ead1cdc8..100f43423f1 100644 --- a/src/gallium/drivers/r300/compiler/radeon_compiler.h +++ b/src/gallium/drivers/r300/compiler/radeon_compiler.h @@ -62,6 +62,8 @@ struct radeon_compiler { int max_alu_insts; unsigned max_tex_insts; + int max_temp_index; + /* Whether to remove unused constants and empty holes in constant space. */ unsigned remove_unused_constants:1; diff --git a/src/gallium/drivers/r300/compiler/radeon_program.c b/src/gallium/drivers/r300/compiler/radeon_program.c index fe5756ebc45..e03f496b282 100644 --- a/src/gallium/drivers/r300/compiler/radeon_program.c +++ b/src/gallium/drivers/r300/compiler/radeon_program.c @@ -71,98 +71,28 @@ void rc_local_transform( } } -struct get_used_temporaries_data { - unsigned char * Used; - unsigned int UsedLength; -}; - -static void get_used_temporaries_cb( - void * userdata, - struct rc_instruction * inst, - rc_register_file file, - unsigned int index, - unsigned int mask) -{ - struct get_used_temporaries_data * d = userdata; - - if (file != RC_FILE_TEMPORARY) - return; - - if (index >= d->UsedLength) - return; - - d->Used[index] |= mask; -} - -/** - * This function fills in the parameter 'used' with a writemask that - * represent which components of each temporary register are used by the - * program. This is meant to be combined with rc_find_free_temporary_list as a - * more efficient version of rc_find_free_temporary. - * @param used The function does not initialize this parameter. - */ -void rc_get_used_temporaries( - struct radeon_compiler * c, - unsigned char * used, - unsigned int used_length) -{ - struct rc_instruction * inst; - struct get_used_temporaries_data d; - d.Used = used; - d.UsedLength = used_length; - - for(inst = c->Program.Instructions.Next; - inst != &c->Program.Instructions; inst = inst->Next) { - - rc_for_all_reads_mask(inst, get_used_temporaries_cb, &d); - rc_for_all_writes_mask(inst, get_used_temporaries_cb, &d); - } -} - -/* Search a list of used temporaries for a free one - * \sa rc_get_used_temporaries - * @note If this functions finds a free temporary, it will mark it as used - * in the used temporary list (param 'used') - * @param used list of used temporaries - * @param used_length number of items in param 'used' - * @param mask which components must be free in the temporary index that is - * returned. - * @return -1 If there are no more free temporaries, otherwise the index of - * a temporary register where the components specified in param 'mask' are - * not being used. - */ -int rc_find_free_temporary_list( - struct radeon_compiler * c, - unsigned char * used, - unsigned int used_length, - unsigned int mask) -{ - int i; - for(i = 0; i < used_length; i++) { - if ((~used[i] & mask) == mask) { - used[i] |= mask; - return i; - } - } - return -1; -} - unsigned int rc_find_free_temporary(struct radeon_compiler * c) { - unsigned char used[RC_REGISTER_MAX_INDEX]; - int free; + /* Find the largest used temp index when called for the first time. */ + if (c->max_temp_index == -1) { + for (struct rc_instruction * inst = c->Program.Instructions.Next; + inst != &c->Program.Instructions; inst = inst->Next) { + const struct rc_opcode_info * opcode = + rc_get_opcode_info(inst->U.I.Opcode); + if (opcode->HasDstReg && + inst->U.I.DstReg.File == RC_FILE_TEMPORARY && + inst->U.I.WriteALUResult == RC_ALURESULT_NONE && + inst->U.I.DstReg.Index > c->max_temp_index) + c->max_temp_index = inst->U.I.DstReg.Index; + } + } - memset(used, 0, sizeof(used)); - - rc_get_used_temporaries(c, used, RC_REGISTER_MAX_INDEX); - - free = rc_find_free_temporary_list(c, used, RC_REGISTER_MAX_INDEX, - RC_MASK_XYZW); - if (free < 0) { + c->max_temp_index++; + if (c->max_temp_index > RC_REGISTER_MAX_INDEX) { rc_error(c, "Ran out of temporary registers\n"); return 0; } - return free; + return c->max_temp_index; } diff --git a/src/gallium/drivers/r300/compiler/radeon_rename_regs.c b/src/gallium/drivers/r300/compiler/radeon_rename_regs.c index 4a124e7d4d1..fceb85c1c4d 100644 --- a/src/gallium/drivers/r300/compiler/radeon_rename_regs.c +++ b/src/gallium/drivers/r300/compiler/radeon_rename_regs.c @@ -48,9 +48,7 @@ */ void rc_rename_regs(struct radeon_compiler *c, void *user) { - unsigned int used_length; struct rc_instruction * inst; - unsigned char * used; struct rc_list * variables; struct rc_list * var_ptr; @@ -62,11 +60,6 @@ void rc_rename_regs(struct radeon_compiler *c, void *user) return; } - used_length = MIN2(2 * rc_recompute_ips(c), RC_REGISTER_MAX_INDEX); - used = memory_pool_malloc(&c->Pool, sizeof(unsigned char) * used_length); - memset(used, 0, sizeof(unsigned char) * used_length); - - rc_get_used_temporaries(c, used, used_length); variables = rc_get_variables(c); for (var_ptr = variables; var_ptr; var_ptr = var_ptr->Next) { @@ -78,8 +71,7 @@ void rc_rename_regs(struct radeon_compiler *c, void *user) continue; } - new_index = rc_find_free_temporary_list(c, used, used_length, - RC_MASK_XYZW); + new_index = rc_find_free_temporary(c); if (new_index < 0) { rc_error(c, "Ran out of temporary registers\n"); return;