Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
{
free_value(gen, desc->value, desc->reg, desc->other_reg, 0);
}
}
else if(desc->kill)
{
save_value(gen, desc->value, desc->reg, desc->other_reg, 1);
}
#ifdef JIT_REG_DEBUG
printf("value = ");
jit_dump_value(stdout, jit_value_get_function(desc->value), desc->value, 0);
printf("\n");
printf("value->in_register = %d\n", desc->value->in_register);
printf("value->reg = %d\n", desc->value->reg);
printf("value->in_global_register = %d\n", desc->value->in_global_register);
printf("value->global_reg = %d\n", desc->value->global_reg);
printf("value->in_frame = %d\n", desc->value->in_frame);
#endif
}
/*@
* @deftypefun void _jit_regs_lookup (char *name)
* Get the pseudo register by its name.
* @end deftypefun
@*/
int
_jit_regs_lookup(char *name)
{
int reg;
if(name)
{
for(reg = 0; reg < JIT_NUM_REGS; reg++)
{
if(strcmp(jit_reg_name(reg), name) == 0)
{
return reg;
}
}
}
return -1;
}
/*@
* @deftypefun void _jit_regs_alloc_global (jit_gencode_t gen, jit_function_t func)
* Perform global register allocation on the values in @code{func}.
* This is called during function compilation just after variable
* liveness has been computed.
* @end deftypefun
@*/
void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func)
{
#if JIT_NUM_GLOBAL_REGS != 0
jit_value_t candidates[JIT_NUM_GLOBAL_REGS];
int num_candidates = 0;
int index, reg, posn, num;
jit_pool_block_t block;
jit_value_t value, temp;
/* If the function has a "try" block, then don't do global allocation
as the "longjmp" for exception throws will wipe out global registers */
if(func->has_try)
{
return;
}
/* If the current function involves a tail call, then we don't do
global register allocation and we also prevent the code generator
from using any of the callee-saved registers. This simplifies
tail calls, which don't have to worry about restoring such registers */
if(func->builder->has_tail_call)
{
for(reg = 0; reg < JIT_NUM_REGS; ++reg)
{
if((jit_reg_flags(reg) & (JIT_REG_FIXED|JIT_REG_CALL_USED)) == 0)
{
jit_reg_set_used(gen->permanent, reg);
}
}
return;
}
/* Scan all values within the function, looking for the most used.
We will replace this with a better allocation strategy later */
block = func->builder->value_pool.blocks;
num = (int)(func->builder->value_pool.elems_per_block);
while(block != 0)
{
if(!(block->next))
{
num = (int)(func->builder->value_pool.elems_in_last);
}
for(posn = 0; posn < num; ++posn)
{
value = (jit_value_t)(block->data + posn * sizeof(struct _jit_value));
if(value->global_candidate && value->usage_count >= JIT_MIN_USED &&
!(value->is_addressable) && !(value->is_volatile))
{
/* Insert this candidate into the list, ordered on count */
index = 0;
while(index < num_candidates &&
value->usage_count <= candidates[index]->usage_count)
{
++index;
}
while(index < num_candidates)
{
temp = candidates[index];
candidates[index] = value;
value = temp;
++index;
}
if(index < JIT_NUM_GLOBAL_REGS)
{
candidates[num_candidates++] = value;
}
}
}
block = block->next;
}
( run in 0.955 second using v1.01-cache-2.11-cpan-119454b85a5 )