/* The cost value that precludes using the register in question. */
#define COST_TOO_MUCH 1000000
+#define COST_COPY 4
+#define COST_SPILL_DIRTY 16
+#define COST_SPILL_DIRTY_GLOBAL 2
+#define COST_SPILL_CLEAN 1
+#define COST_SPILL_CLEAN_GLOBAL 1
+
/* Value usage flags. */
#define VALUE_INPUT 1
#define VALUE_USED 2
return 1;
}
- if(desc->value->has_global_register)
- {
- if(desc->value->global_reg != desc->reg
- && !(desc->value->in_register && desc->value->reg == desc->reg))
- {
- desc->copy = 1;
- }
- }
- else
+ if(index > 0 || regs->ternary)
{
- if(!desc->value->in_register)
+ if(desc->value->has_global_register)
{
- desc->load = 1;
+ if(desc->value->global_reg != desc->reg
+ && !(desc->value->in_register && desc->value->reg == desc->reg))
+ {
+ desc->copy = 1;
+ }
}
- else if(desc->value->reg != desc->reg)
+ else
{
- desc->copy = 1;
+ if(!desc->value->in_register)
+ {
+ desc->load = 1;
+ }
+ else if(desc->value->reg != desc->reg)
+ {
+ desc->copy = 1;
+ }
}
- }
- if(index > 0 || regs->ternary)
- {
if(desc->value->is_constant)
{
desc->kill = 1;
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);
printf("reg = %d\n", desc->reg);
printf("other_reg = %d\n", desc->other_reg);
printf("live = %d\n", desc->live);
}
if(value->has_global_register)
{
- if(!value->in_global_register)
+ if(value->in_global_register)
{
- cost += 1;
+ cost += COST_SPILL_CLEAN_GLOBAL;
+ }
+ else
+ {
+ cost += COST_SPILL_DIRTY_GLOBAL;
}
}
else
{
- if(!value->in_frame)
+ if(value->in_frame)
+ {
+ cost += COST_SPILL_CLEAN;
+ }
+ else
{
- cost += 10;
+ cost += COST_SPILL_DIRTY;
}
}
}
int type;
int need_pair;
int reg, other_reg;
+ int cost, copy_cost;
int suitable_reg;
int suitable_cost;
int suitable_age;
- int move, cost;
if(index >= 0)
{
{
continue;
}
- move = 0;
+ copy_cost = 0;
cost = compute_spill_cost(gen, regs, reg, -1);
}
else if(desc->value->has_global_register)
{
continue;
}
- move = ((output | desc->value->in_global_register) == 0);
+ copy_cost = ((output | desc->value->in_global_register) == 0);
cost = 0;
}
else if(jit_reg_is_used(gen->permanent, reg))
}
else if(desc->value->in_register && reg == desc->value->reg)
{
- move = ((output | desc->value->in_global_register) != 0);
+ copy_cost = ((output | desc->value->in_global_register) != 0);
if(clobbers_register(gen, regs, index, reg, -1))
{
cost = compute_spill_cost(gen, regs, reg, -1);
}
else
{
- move = 1;
+ copy_cost = 1;
cost = compute_spill_cost(gen, regs, reg, -1);
}
}
|| (other_reg >= 0
&& jit_reg_is_used(regs->clobber, other_reg))))
{
- move = 0;
+ copy_cost = 0;
cost = compute_spill_cost(gen, regs, reg, other_reg);
}
else
{
- move = 0;
+ copy_cost = 0;
cost = 0;
}
}
else
{
- move = 1;
+ copy_cost = 1;
cost = compute_spill_cost(gen, regs, reg, other_reg);
}
}
else
{
- move = 0;
+ copy_cost = 0;
cost = compute_spill_cost(gen, regs, reg, other_reg);
}
}
- if((move + cost) < suitable_cost
- || (cost > 0 && (move + cost) == suitable_cost
+#if COST_COPY != 1
+ if(copy_cost)
+ {
+ copy_cost = COST_COPY;
+ }
+#endif
+ if((cost + copy_cost) < suitable_cost
+ || (cost > 0 && (cost + copy_cost) == suitable_cost
&& gen->contents[reg].age < suitable_age))
{
/* This is the oldest suitable register of this type */
suitable_reg = reg;
- suitable_cost = move + cost;
+ suitable_cost = cost + copy_cost;
suitable_age = gen->contents[reg].age;
}
}
#endif
/* Never free global registers. */
- if(value->has_global_register)
+ if(value->has_global_register && value->global_reg == reg)
{
return;
}
/* First take care of values that reside in global registers. */
if(value->has_global_register)
{
- if(value->global_reg != reg && !value->in_global_register)
+ /* Never free global registers. */
+ if(value->global_reg == reg)
+ {
+ return;
+ }
+
+ if(!value->in_global_register)
{
_jit_gen_spill_reg(gen, reg, other_reg, value);
value->in_global_register = 1;
}
+ if(free)
+ {
+ unbind_value(gen, value, reg, other_reg);
+ }
return;
}
printf("\n");
printf("value->in_register = %d\n", desc->value->in_register);
printf("value->reg = %d\n", desc->value->reg);
- printf("value->in_gloable_register = %d\n", desc->value->in_global_register);
+ 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
}
printf("\n");
printf("value->in_register = %d\n", desc->value->in_register);
printf("value->reg = %d\n", desc->value->reg);
- printf("value->in_gloable_register = %d\n", desc->value->in_global_register);
+ 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
}
}
#ifdef JIT_REG_DEBUG
- dump_regs(gen, "enter _jit_regs_commit");
+ dump_regs(gen, "leave _jit_regs_commit");
#endif
}