Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
}
if((clobber & CLOBBER_REG) != 0)
{
printf("clobber reg\n");
}
if((clobber & CLOBBER_OTHER_REG) != 0)
{
printf("clobber other reg\n");
}
#endif
/* See if this is an input value and whether it is alive. */
if(regs->ternary)
{
is_input = 1;
is_live_input = desc->live;
is_used_input = desc->used;
}
else if(index > 0)
{
is_input = 1;
if(regs->descs[0].value == desc->value)
{
is_live_input = is_used_input = 0;
}
else
{
is_live_input = desc->live;
is_used_input = desc->used;
}
}
else
{
is_input = is_live_input = is_used_input = 0;
}
if(is_input)
{
/* Find the register the value is already in (if any). */
if(desc->value->in_register)
{
reg = desc->value->reg;
if(gen->contents[reg].is_long_start)
{
other_reg = jit_reg_other_reg(reg);
}
else
{
other_reg = -1;
}
}
else
{
reg = -1;
other_reg = -1;
}
/* See if the input value is thrashed by other inputs. The allocator
tries to avoid thrashing so it may only take place if the register
is assigned explicitly. For x87 registers the problem of thrashing
may be best solved with fxch but as the stack registers are never
assigned explicitely there is no such problem for them at all. */
if(reg >= 0)
{
if(index != 0 && regs->ternary
&& !are_values_equal(desc, ®s->descs[0]))
{
if(reg == regs->descs[0].reg
|| reg == regs->descs[0].other_reg
|| (other_reg >= 0
&& (other_reg == regs->descs[0].reg
|| other_reg == regs->descs[0].other_reg)))
{
desc->thrash = 1;
}
}
if(index != 1 && !are_values_equal(desc, ®s->descs[1]))
{
if(reg == regs->descs[1].reg
|| reg == regs->descs[1].other_reg
|| (other_reg >= 0
&& (other_reg == regs->descs[1].reg
|| other_reg == regs->descs[1].other_reg)))
{
desc->thrash = 1;
}
}
if(index != 2 && !are_values_equal(desc, ®s->descs[2]))
{
if(reg == regs->descs[2].reg
|| reg == regs->descs[2].other_reg
|| (other_reg >= 0
&& (other_reg == regs->descs[2].reg
|| other_reg == regs->descs[2].other_reg)))
{
desc->thrash = 1;
}
}
if(desc->thrash)
{
reg = -1;
other_reg = -1;
}
}
/* See if the value needs to be loaded or copied or none. */
if(reg != desc->reg)
{
if(desc->value->has_global_register)
{
desc->copy = (desc->value->global_reg != desc->reg);
}
else if(reg < 0)
{
desc->load = 1;
}
else
{
desc->copy = 1;
}
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
/* This depends on choose_input_order()
doing its job on the next step. */
use_cost = 0;
}
#ifdef JIT_REG_STACK
else if(regs->reversible && regs->no_pop)
{
/* This depends on choose_input_order()
doing its job on the next step. */
use_cost = 0;
}
#endif
else
{
use_cost = COST_THRASH;
}
}
else
{
use_cost = COST_COPY;
}
if(regs->descs[0].value->has_global_register)
{
use_cost += COST_GLOBAL_BIAS;
}
}
if(!jit_reg_is_used(regs->clobber, reg)
&& !(other_reg >= 0 && jit_reg_is_used(regs->clobber, other_reg)))
{
use_cost += compute_spill_cost(gen, regs, reg, other_reg);
}
#ifdef JIT_REG_DEBUG
printf("reg = %d, other_reg = %d, use_cost = %d\n", reg, other_reg, use_cost);
#endif
if(use_cost < suitable_cost
|| (use_cost == suitable_cost
&& gen->contents[reg].num_values > 0
&& gen->contents[reg].age < suitable_age))
{
suitable_reg = reg;
suitable_other_reg = other_reg;
suitable_cost = use_cost;
suitable_age = gen->contents[reg].age;
}
}
if(suitable_reg >= 0)
{
set_regdesc_register(gen, regs, 0, suitable_reg, suitable_other_reg);
}
else
{
jit_exception_builtin(JIT_RESULT_COMPILE_ERROR);
}
}
/*
* Select the best argument order for binary ops. The posibility to select
* the order exists only for commutative ops and for some x87 floating point
* instructions. Those x87 instructions have variants with reversed
* destination register.
*/
static void
choose_input_order(jit_gencode_t gen, _jit_regs_t *regs)
{
jit_value_t value;
value = regs->descs[2].value;
if(value && value != regs->descs[1].value
&& ((value->in_register
&& value->reg == regs->descs[0].reg)
|| (value->in_global_register
&& value->global_reg == regs->descs[0].reg)))
{
#ifdef JIT_REG_STACK
if(regs->reversible && regs->no_pop)
{
regs->dest_input_index = 2;
}
else
#endif
{
if(regs->commutative)
{
swap_values(®s->descs[1], ®s->descs[2]);
}
regs->dest_input_index = 1;
}
}
else if(regs->descs[1].value)
{
regs->dest_input_index = 1;
}
else
{
regs->dest_input_index = 0;
}
}
static void
choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
{
_jit_regclass_t *regclass;
_jit_regdesc_t *desc;
_jit_regdesc_t *desc2;
int reg_index, reg, other_reg;
int use_cost;
int suitable_reg, suitable_other_reg;
int suitable_cost;
int suitable_age;
int clobber;
#ifdef JIT_REG_DEBUG
printf("choose_input_register(%d)\n", index);
#endif
desc = ®s->descs[index];
if(!desc->value)
( run in 2.096 seconds using v1.01-cache-2.11-cpan-d7f47b0818f )