示例#1
0
/**
 * analyze enough to decide if we should lower the switch
 */
static void analyse_switch0(switch_info_t *info, ir_node *switchn)
{
	const ir_switch_table *table      = get_Switch_table(switchn);
	size_t                 n_entries  = ir_switch_table_get_n_entries(table);
	ir_mode               *mode       = get_irn_mode(get_Switch_selector(switchn));
	ir_tarval             *switch_min = get_mode_max(mode);
	ir_tarval             *switch_max = get_mode_min(mode);
	unsigned               num_cases  = 0;

	for (size_t e = 0; e < n_entries; ++e) {
		const ir_switch_table_entry *entry
			= ir_switch_table_get_entry_const(table, e);
		if (entry->pn == pn_Switch_default)
			continue;

		if (tarval_cmp(entry->min, switch_min) == ir_relation_less)
			switch_min = entry->min;
		if (tarval_cmp(entry->max, switch_max) == ir_relation_greater)
			switch_max = entry->max;

		++num_cases;
	}

	info->switchn    = switchn;
	info->switch_min = switch_min;
	info->switch_max = switch_max;
	info->num_cases  = num_cases;
}
示例#2
0
static void check_mode(ir_mode *mode)
{
	ir_tarval *zero       = get_mode_null(mode);
	ir_tarval *minus_zero = tarval_neg(zero);
	ir_tarval *min        = get_mode_min(mode);
	ir_tarval *max        = get_mode_max(mode);
	ir_tarval *inf        = get_mode_infinite(mode);
	ir_tarval *minus_inf  = tarval_neg(inf);
	ir_tarval *one        = get_mode_one(mode);
	ir_tarval *minus_one  = tarval_neg(one);

	/* some random arithmetics */
	ir_tarval *int_zero      = get_mode_null(mode_Is);
	ir_tarval *int_one       = get_mode_one(mode_Is);
	ir_tarval *int_minus_one = get_mode_all_one(mode_Is);
	ir_tarval *int_min       = get_mode_min(mode_Is);
	ir_tarval *int_max       = get_mode_max(mode_Is);
	assert(tarval_convert_to(zero, mode_Is) == int_zero);
	assert(tarval_convert_to(minus_zero, mode_Is) == int_zero);
	assert(tarval_convert_to(one, mode_Is) == int_one);
	assert(tarval_convert_to(minus_one, mode_Is) == int_minus_one);
	assert(tarval_convert_to(min, mode_Is) == int_min);
	assert(tarval_convert_to(max, mode_Is) == int_max);
	assert(tarval_convert_to(inf, mode_Is) == int_max);
	assert(tarval_convert_to(minus_inf, mode_Is) == int_min);

	static const char *const ints[] = {
		"0", "1", "-1", "12345", "2", "4", "8", "16", "32", "64", "128", "256",
		"512", "1024", "2048", "127", "2047"
	};
	for (unsigned i = 0; i < ARRAY_SIZE(ints); ++i) {
		const char *str = ints[i];
		ir_tarval *flt = new_tarval_from_str(str, strlen(str), mode);
		ir_tarval *intt = new_tarval_from_str(str, strlen(str), mode_Is);
		assert(tarval_convert_to(flt, mode_Is) == intt);
		assert(tarval_convert_to(intt, mode) == flt);
	}
}
示例#3
0
bool enum_bitfield_big_enough(enum_t *enume, type_t *base_type,
                              unsigned bitfield_size)
{
	ir_mode    *mode        = get_ir_mode_storage(base_type);
	ir_tarval  *max         = get_mode_max(mode);
	ir_tarval  *min         = get_mode_min(mode);
	bool       is_signed    = is_type_signed(base_type);
	unsigned   mode_size    = get_mode_size_bits(mode);
	unsigned   shift_amount = mode_size - bitfield_size + is_signed;
	ir_tarval *adjusted_max;
	ir_tarval *adjusted_min;
	/* corner case: signed mode with just sign bit results in shift_amount
	 * being as big as mode_size triggering "modulo shift" which is not what
	 * we want here. */
	if (shift_amount >= mode_size) {
		assert(bitfield_size == 1 && mode_is_signed(mode));
		adjusted_max = get_mode_null(mode);
		adjusted_min = get_mode_all_one(mode);
	} else {
		adjusted_max = tarval_shr_unsigned(max, shift_amount);
		adjusted_min = tarval_shrs_unsigned(min, shift_amount);
	}

	for (entity_t *entry = enume->first_value;
	     entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
	     entry = entry->base.next) {
		ir_tarval *tv = get_enum_value(&entry->enum_value);
		if (tv == NULL)
			continue;
		ir_tarval *tvc = tarval_convert_to(tv, mode);
		if (tarval_cmp(tvc, adjusted_min) == ir_relation_less
		 || tarval_cmp(tvc, adjusted_max) == ir_relation_greater) {
			return false;
		}
	}
	return true;
}
示例#4
0
/**
 * construct an interval from a value
 *
 * @return the filled interval or NULL if no interval
 *         can be created (happens only on floating point
 */
static interval_t *get_interval_from_tv(interval_t *iv, ir_tarval *tv)
{
	ir_mode *mode = get_tarval_mode(tv);

	if (tv == tarval_bad) {
		if (mode_is_float(mode)) {
			/* NaN could be included which we cannot handle */
			iv->min   = tarval_bad;
			iv->max   = tarval_bad;
			iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
			return NULL;
		} else {
			/* [-oo, +oo] */
			iv->min   = get_mode_min(mode);
			iv->max   = get_mode_max(mode);
			iv->flags = MIN_INCLUDED | MAX_INCLUDED;
			return iv;
		}
	}

	if (mode_is_float(mode)) {
		if (tv == get_mode_NAN(mode)) {
			/* arg, we cannot handle NaN's. */
			iv->min   = tarval_bad;
			iv->max   = tarval_bad;
			iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
			return NULL;
		}
	}

	/* [tv, tv] */
	iv->min   = tv;
	iv->max   = tv;
	iv->flags = MIN_INCLUDED | MAX_INCLUDED;

	return iv;
}
示例#5
0
/**
 * construct an interval from a Confirm
 *
 * @param iv       an empty interval, will be filled
 * @param bound    the bound value
 * @param relation the Confirm compare relation
 *
 * @return the filled interval or NULL if no interval
 *         can be created (happens only on floating point
 */
static interval_t *get_interval(interval_t *iv, ir_node *bound, ir_relation relation)
{
	ir_mode   *mode = get_irn_mode(bound);
	ir_tarval *tv   = value_of(bound);

	if (tv == tarval_bad) {
		/* There is nothing we could do here. For integer
		 * modes we could return [-oo, +oo], but there is
		 * nothing we could deduct from such an interval.
		 * So, speed things up and return unknown.
		 */
		iv->min   = tarval_bad;
		iv->max   = tarval_bad;
		iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
		return NULL;
	}

	if (mode_is_float(mode)) {
		if (tv == get_mode_NAN(mode)) {
			/* arg, we cannot handle NaN's. */
			iv->min   = tarval_bad;
			iv->max   = tarval_bad;
			iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;

			return NULL;
		}
	}

	/* check which side is known */
	switch (relation) {
	case ir_relation_equal:
		/* [tv, tv] */
		iv->min   =
			iv->max   = tv;
		iv->flags = MIN_INCLUDED | MAX_INCLUDED;
		break;

	case ir_relation_less_equal:
		/* [-oo, tv] */
		iv->min   = get_mode_min(mode);
		iv->max   = tv;
		iv->flags = MIN_INCLUDED | MAX_INCLUDED;
		break;

	case ir_relation_less:
		/* [-oo, tv) */
		iv->min   = get_mode_min(mode);
		iv->max   = tv;
		iv->flags = MIN_INCLUDED | MAX_EXCLUDED;
		break;

	case ir_relation_greater:
		/* (tv, +oo] */
		iv->min   = tv;
		iv->max   = get_mode_max(mode);
		iv->flags = MIN_EXCLUDED | MAX_INCLUDED;
		break;

	case ir_relation_greater_equal:
		/* [tv, +oo] */
		iv->min   = tv;
		iv->max   = get_mode_max(mode);
		iv->flags = MIN_INCLUDED | MAX_INCLUDED;
		break;

	case ir_relation_less_equal_greater:
		/*
		 * Ordered means, that at least neither
		 * our bound nor our value ara NaN's
		 */
		/* [-oo, +oo] */
		iv->min   = get_mode_min(mode);
		iv->max   = get_mode_max(mode);
		iv->flags = MIN_INCLUDED | MAX_INCLUDED;
		break;

	default:
		/*
		 * We do not handle UNORDERED, as a NaN
		 * could be included in the interval.
		 */
		iv->min   = tarval_bad;
		iv->max   = tarval_bad;
		iv->flags = MIN_EXCLUDED | MAX_EXCLUDED;
		return NULL;
	}

	if (iv->min != tarval_bad && iv->max != tarval_bad)
		return iv;
	return NULL;
}