Exemplo n.º 1
0
ir_node *gcji_allocate_array(ir_type *eltype, ir_node *count)
{
	ir_node *jclass = gcji_get_runtime_classinfo(eltype);
	ir_node *res;
	ir_node *new_mem;
	if (is_Primitive_type(eltype)) {
		ir_node *addr      = new_Address(gcj_new_prim_array_entity);
		ir_node *args[]    = { jclass, count };
		ir_type *call_type = get_entity_type(gcj_new_prim_array_entity);
		ir_node *mem       = get_store();
		ir_node *call      = new_Call(mem, addr, ARRAY_SIZE(args), args,
		                              call_type);
		ir_node *ress      = new_Proj(call, mode_T, pn_Call_T_result);
		new_mem = new_Proj(call, mode_M, pn_Call_M);
		res     = new_r_Proj(ress, mode_reference, 0);
	} else {
		ir_node *addr      = new_Address(gcj_new_object_array_entity);
		ir_node *null      = new_Const(get_mode_null(mode_reference));
		ir_node *args[]    = { count, jclass, null };
		ir_type *call_type = get_entity_type(gcj_new_object_array_entity);
		ir_node *mem       = get_store();
		ir_node *call      = new_Call(mem, addr, ARRAY_SIZE(args), args,
		                              call_type);
		ir_node *ress      = new_Proj(call, mode_T, pn_Call_T_result);
		new_mem = new_Proj(call, mode_M, pn_Call_M);
		res     = new_Proj(ress, mode_reference, 0);
	}

	ir_node *assure_vptr = new_VptrIsSet(new_mem, res, type_jarray);
	ir_node *new_mem2    = new_Proj(assure_vptr, mode_M, pn_VptrIsSet_M);
	ir_node *res2        = new_Proj(assure_vptr, mode_reference,
	                                pn_VptrIsSet_res);
	set_store(new_mem2);
	return res2;
}
Exemplo n.º 2
0
static ir_tarval *literal_to_tarval_(const literal_expression_t *literal,
                                    ir_mode *mode)
{
	switch (literal->base.kind) {
	case EXPR_LITERAL_INTEGER:
		assert(literal->target_value != NULL);
		return literal->target_value;

	case EXPR_LITERAL_FLOATINGPOINT:
		return new_tarval_from_str(literal->value->begin,
		                           literal->value->size, mode);

	case EXPR_LITERAL_BOOLEAN:
		if (literal->value->begin[0] == 't') {
			return get_mode_one(mode);
		} else {
			assert(literal->value->begin[0] == 'f');
	case EXPR_LITERAL_MS_NOOP:
			return get_mode_null(mode);
		}

	default:
		panic("invalid literal kind");
	}
}
Exemplo n.º 3
0
ir_node *get_atomic_ent_value(const ir_entity *entity)
{
	ir_initializer_t *initializer = get_entity_initializer(entity);

	assert(is_atomic_entity(entity));
	if (initializer == NULL) {
		ir_type *type = get_entity_type(entity);
		return new_r_Unknown(get_const_code_irg(), get_type_mode(type));
	}

	switch (get_initializer_kind(initializer)) {
	case IR_INITIALIZER_NULL: {
		ir_type *type = get_entity_type(entity);
		ir_mode *mode = get_type_mode(type);
		return new_r_Const(get_const_code_irg(), get_mode_null(mode));
	}
	case IR_INITIALIZER_TARVAL: {
		ir_tarval *tv = get_initializer_tarval_value(initializer);
		return new_r_Const(get_const_code_irg(), tv);
	}
	case IR_INITIALIZER_CONST:
		return get_initializer_const_value(initializer);
	case IR_INITIALIZER_COMPOUND:
		panic("compound initializer in atomic entity not allowed (%+F)", entity);
	}

	panic("invalid initializer kind (%+F)", entity);
}
Exemplo n.º 4
0
complex_constant fold_complex_literal(literal_expression_t const *const literal)
{
	type_t    *type     = skip_typeref(literal->base.type);
	ir_mode   *mode     = get_complex_mode_storage(type);
	ir_tarval *litvalue = literal_to_tarval_(literal, mode);
	ir_tarval *zero     = get_mode_null(mode);
	return (complex_constant) {
		zero,
		litvalue
	};
}
Exemplo n.º 5
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);
	}
}
Exemplo n.º 6
0
static ir_node *gcji_get_arrayclass(ir_node *block, ir_node **mem,
                                    ir_node *array_class_ref)
{
	ir_graph *irg      = get_irn_irg(block);
	ir_node *addr      = new_r_Address(irg, gcj_get_array_class_entity);
	ir_node *null      = new_r_Const(irg, get_mode_null(mode_reference));
	ir_node *args[]    = { array_class_ref, null };
	ir_type *call_type = get_entity_type(gcj_get_array_class_entity);
	ir_node *call      = new_r_Call(block, *mem, addr, ARRAY_SIZE(args), args,
	                                call_type);
	ir_node *new_mem   = new_Proj(call, mode_M, pn_Call_M);
	ir_node *ress      = new_Proj(call, mode_T, pn_Call_T_result);
	ir_node *res       = new_Proj(ress, mode_reference, 0);
	*mem = new_mem;
	return res;
}
Exemplo n.º 7
0
static complex_constant fold_complex_cast(const unary_expression_t *expression)
{
	const expression_t *const value     = expression->value;
	type_t             *const from_type = skip_typeref(value->base.type);
	type_t             *const to_type   = skip_typeref(expression->base.type);
	ir_mode            *const mode      = get_complex_mode_storage(to_type);

	if (is_type_complex(from_type)) {
		complex_constant const folded = fold_complex(value);
		return convert_complex_constant(folded, mode);
	} else {
		ir_tarval *const folded = fold_expression(value);
		ir_tarval *const casted = tarval_convert_to(folded, mode);
		ir_tarval *const zero   = get_mode_null(mode);
		return (complex_constant) { casted, zero };
	}
}
Exemplo n.º 8
0
static ir_node *gcji_instanceof(ir_node *objptr, ir_type *classtype,
                                ir_graph *irg, ir_node *block, ir_node **mem)
{
	ir_node *jclass    = gcji_get_runtime_classinfo_(block, mem, classtype);
	ir_node *addr      = new_r_Address(irg, gcj_instanceof_entity);
	ir_node *args[]    = { objptr, jclass };
	ir_type *call_type = get_entity_type(gcj_instanceof_entity);
	ir_node *call      = new_r_Call(block, *mem, addr, ARRAY_SIZE(args), args,
	                                call_type);
	ir_node *new_mem   = new_r_Proj(call, mode_M, pn_Call_M);
	ir_node *ress      = new_r_Proj(call, mode_T, pn_Call_T_result);
	ir_node *call_res  = new_r_Proj(ress, mode_int, 0);
	ir_node *zero      = new_r_Const(irg, get_mode_null(mode_int));
	ir_node *res       = new_r_Cmp(block, call_res, zero,
	                               ir_relation_less_greater);
	*mem = new_mem;
	return res;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
void determine_enum_values(enum_t *const enume)
{
	if (enume->error)
		return;

	ir_mode   *const mode    = atomic_modes[enume->akind];
	ir_tarval *const one     = get_mode_one(mode);
	ir_tarval *      tv_next = get_mode_null(mode);

	for (entity_t *entry = enume->first_value;
	     entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
	     entry = entry->base.next) {
		expression_t *const init = entry->enum_value.value;
		if (init != NULL) {
			type_t *const init_type = skip_typeref(init->base.type);
			if (!is_type_valid(init_type))
				continue;
			tv_next = fold_expression(init);
		}
		assert(entry->enum_value.tv == NULL || entry->enum_value.tv == tv_next);
		entry->enum_value.tv = tv_next;
		tv_next = tarval_add(tv_next, one);
	}
}
Exemplo n.º 11
0
/*
 * Check, if the value of a node is != 0.
 *
 * This is a often needed case, so we handle here Confirm
 * nodes too.
 */
int value_not_zero(const ir_node *n, const ir_node **confirm)
{
#define RET_ON(x)  if (x) { *confirm = n; return 1; } break

	ir_tarval *tv;
	ir_mode *mode = get_irn_mode(n);
	ir_relation relation;

	*confirm = NULL;

	/* there might be several Confirms one after other that form an interval */
	for (;;) {
		if (is_Minus(n)) {
			/* we can safely skip Minus when checking for != 0 */
			n = get_Minus_op(n);
			continue;
		}
		if (! is_Confirm(n))
			break;

		/*
		 * Note: A Confirm is never after a Const. So,
		 * we simply can check the bound for being a Const
		 * without the fear that is might be hidden by a further Confirm.
		 */
		tv = value_of(get_Confirm_bound(n));
		if (tv == tarval_bad) {
			n = get_Confirm_value(n);
			continue;
		}

		relation = tarval_cmp(tv, get_mode_null(mode));

		/*
		 * Beware: C might by a NaN. It is not clear, what we should do
		 * than. Of course a NaN is != 0, but we might use this function
		 * to remove up Exceptions, and NaN's might generate Exception.
		 * So, we do NOT handle NaNs here for safety.
		 *
		 * Note that only the C != 0 case need additional checking.
		 */
		switch (get_Confirm_relation(n)) {
		case ir_relation_equal: /* n == C /\ C != 0 ==> n != 0 */
			RET_ON(relation != ir_relation_equal && relation != ir_relation_unordered);
		case ir_relation_less_greater: /* n != C /\ C == 0 ==> n != 0 */
			RET_ON(relation == ir_relation_equal);
		case ir_relation_less: /* n <  C /\ C <= 0 ==> n != 0 */
			RET_ON(relation == ir_relation_less || relation == ir_relation_equal);
		case ir_relation_less_equal: /* n <= C /\ C <  0 ==> n != 0 */
			RET_ON(relation == ir_relation_less);
		case ir_relation_greater_equal: /* n >= C /\ C >  0 ==> n != 0 */
			RET_ON(relation == ir_relation_greater);
		case ir_relation_greater: /* n >  C /\ C >= 0 ==> n != 0 */
			RET_ON(relation == ir_relation_greater || relation == ir_relation_equal);
		default:
			break;
		}
		n = get_Confirm_value(n);
	}
	/* global entities are never NULL */
	if (is_SymConst_addr_ent(n))
		return true;

	tv = value_of(n);
	if (tv == tarval_bad)
		return false;

	relation = tarval_cmp(tv, get_mode_null(mode));

	/* again, need check for NaN */
	return (relation != ir_relation_equal) && (relation != ir_relation_unordered);

#undef RET_ON
}
Exemplo n.º 12
0
/*
 * Check, if the value of a node can be confirmed >= 0 or <= 0,
 * If the mode of the value did not honor signed zeros, else
 * check for >= 0 or < 0.
 */
ir_value_classify_sign classify_value_sign(ir_node *n)
{
	ir_tarval *tv, *c;
	ir_mode *mode;
	ir_relation cmp, ncmp;
	int negate = 1;

	for (;;) {
		unsigned code = get_irn_opcode(n);

		switch (code) {
		case iro_Minus:
			negate *= -1;
			n = get_Minus_op(n);
			continue;
		case iro_Confirm:
			break;
		default:
			return value_classified_unknown;
		}
		break;
	}
	if (!is_Confirm(n))
		return value_classified_unknown;

	tv  = value_of(get_Confirm_bound(n));
	if (tv == tarval_bad)
		return value_classified_unknown;

	mode = get_irn_mode(n);

	/*
	 * We can handle only >=, >, <, <= cases.
	 * We could handle == too, but this will be optimized into
	 * a constant either.
	 *
	 * Note that for integer modes we have a slightly better
	 * optimization possibilities, so we handle this
	 * different.
	 */
	cmp = get_Confirm_relation(n);

	switch (cmp) {
	case ir_relation_less:
		/*
		 * must be x < c <= 1 to be useful if integer mode and -0 = 0
		 *         x < c <= 0 to be useful else
		 */
	case ir_relation_less_equal:
		/*
		 * must be x <= c < 1 to be useful if integer mode and -0 = 0
		 *         x <= c < 0 to be useful else
		 */
		c = mode_is_int(mode) && mode_honor_signed_zeros(mode) ?
			get_mode_one(mode) : get_mode_null(mode);

		ncmp = tarval_cmp(tv, c);
		if (ncmp == ir_relation_equal)
			ncmp = ir_relation_less_equal;

		if (cmp != (ncmp ^ ir_relation_equal))
			return value_classified_unknown;

		/* yep, negative */
		return value_classified_negative * negate;

	case ir_relation_greater_equal:
		/*
		 * must be x >= c > -1 to be useful if integer mode
		 *         x >= c >= 0 to be useful else
		 */
	case ir_relation_greater:
		/*
		 * must be x > c >= -1 to be useful if integer mode
		 *         x > c >= 0 to be useful else
		 */
		if (mode_is_int(mode)) {
			c = get_mode_minus_one(mode);

			ncmp = tarval_cmp(tv, c);
			if (ncmp == ir_relation_equal)
				ncmp = ir_relation_greater_equal;

			if (cmp != (ncmp ^ ir_relation_equal))
				return value_classified_unknown;
		} else {
			c = get_mode_minus_one(mode);

			ncmp = tarval_cmp(tv, c);

			if (ncmp != ir_relation_equal && ncmp != ir_relation_greater)
				return value_classified_unknown;
		}

		/* yep, positive */
		return value_classified_positive * negate;

	default:
		return value_classified_unknown;
	}
}