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, &regs->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, &regs->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, &regs->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(&regs->descs[1], &regs->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 = &regs->descs[index];
	if(!desc->value)



( run in 2.096 seconds using v1.01-cache-2.11-cpan-d7f47b0818f )