static ir_tarval *builtin_constant_to_tarval(
		builtin_constant_expression_t const *const expression)
{
	ir_mode *const mode = get_ir_mode_storage(expression->base.type);
	bool     const v    = is_constant_expression(expression->value) != EXPR_CLASS_VARIABLE;
	return create_tarval_from_bool(mode, v);
}
Exemple #2
0
bool is_linktime_constant(const expression_t *expression)
{
	switch (expression->kind) {
	case EXPR_SELECT:
		/* TODO */
		return false;
	case EXPR_ARRAY_ACCESS:
		/* TODO */
		return false;
	case EXPR_UNARY_DEREFERENCE:
		return is_constant_expression(expression->unary.value);
	default:
		return false;
	}
}
complex_constant fold_complex(const expression_t *expression)
{
	assert(is_constant_expression(expression) >= EXPR_CLASS_CONSTANT);
	switch (expression->kind) {
	case EXPR_BINARY_ADD:
		return fold_complex_binop(&expression->binary, fold_complex_add);
	case EXPR_BINARY_SUB:
		return fold_complex_binop(&expression->binary, fold_complex_sub);
	case EXPR_BINARY_MUL:
		return fold_complex_binop(&expression->binary, fold_complex_mul);
	case EXPR_BINARY_DIV:
		return fold_complex_binop(&expression->binary, fold_complex_div);
	case EXPR_UNARY_PLUS:
		return fold_complex(expression->unary.value);
	case EXPR_UNARY_NEGATE:
		return fold_complex_negate(&expression->unary);
	case EXPR_UNARY_COMPLEMENT:
		return fold_complex_complement(&expression->unary);
	case EXPR_LITERAL_INTEGER:
	case EXPR_LITERAL_FLOATINGPOINT:
		return fold_complex_literal(&expression->literal);
	case EXPR_CONDITIONAL:
		return fold_complex_conditional(&expression->conditional);
	case EXPR_UNARY_CAST:
		return fold_complex_cast(&expression->unary);
	case EXPR_ARRAY_ACCESS:
	case EXPR_BINARY_ADD_ASSIGN:
	case EXPR_BINARY_ASSIGN:
	case EXPR_BINARY_COMMA:
	case EXPR_BINARY_DIV_ASSIGN:
	case EXPR_BINARY_MUL_ASSIGN:
	case EXPR_BINARY_SUB_ASSIGN:
	case EXPR_CALL:
	case EXPR_REFERENCE:
	case EXPR_SELECT:
	case EXPR_STATEMENT:
	case EXPR_UNARY_DEREFERENCE:
	case EXPR_UNARY_POSTFIX_DECREMENT:
	case EXPR_UNARY_POSTFIX_INCREMENT:
	case EXPR_UNARY_PREFIX_DECREMENT:
	case EXPR_UNARY_PREFIX_INCREMENT:
		panic("invalid expression kind for constant folding");

	case NEVER_COMPLEX_CASES:
		break;
	}
	panic("internal error: non-complex expression in fold_complex");
}
Exemple #4
0
bool is_constant_expression(const expression_t *expression)
{
	switch (expression->kind) {
	case EXPR_INT_CONST:
	case EXPR_FLOAT_CONST:
	case EXPR_BOOL_CONST:
	case EXPR_NULL_POINTER:
	case EXPR_SIZEOF:
		return true;

	case EXPR_STRING_CONST:
	case EXPR_FUNC:
	case EXPR_UNARY_INCREMENT:
	case EXPR_UNARY_DECREMENT:
	case EXPR_UNARY_DEREFERENCE:
	case EXPR_BINARY_ASSIGN:
	case EXPR_SELECT:
	case EXPR_ARRAY_ACCESS:
		return false;

	case EXPR_UNARY_TAKE_ADDRESS:
		return is_linktime_constant(expression->unary.value);

	case EXPR_REFERENCE: {
		entity_t *entity = expression->reference.entity;
		if (entity->kind == ENTITY_CONSTANT)
			return true;
		return false;
	}

	case EXPR_CALL:
		/* TODO: we might introduce pure/side effect free calls */
		return false;

	case EXPR_UNARY_CAST:
	case EXPR_UNARY_NEGATE:
	case EXPR_UNARY_NOT:
	case EXPR_UNARY_BITWISE_NOT:
		return is_constant_expression(expression->unary.value);

	case EXPR_BINARY_ADD:
	case EXPR_BINARY_SUB:
	case EXPR_BINARY_MUL:
	case EXPR_BINARY_DIV:
	case EXPR_BINARY_MOD:
	case EXPR_BINARY_EQUAL:
	case EXPR_BINARY_NOTEQUAL:
	case EXPR_BINARY_LESS:
	case EXPR_BINARY_LESSEQUAL:
	case EXPR_BINARY_GREATER:
	case EXPR_BINARY_GREATEREQUAL:
	case EXPR_BINARY_AND:
	case EXPR_BINARY_OR:
	case EXPR_BINARY_XOR:
	case EXPR_BINARY_SHIFTLEFT:
	case EXPR_BINARY_SHIFTRIGHT:
	/* not that lazy and/or are not constant if their value is clear after
	 * evaluating the left side. This is because we can't (always) evaluate the
	 * left hand side until the ast2firm phase, and therefore can't determine
	 * constness */
	case EXPR_BINARY_LAZY_AND:
	case EXPR_BINARY_LAZY_OR:
		return is_constant_expression(expression->binary.left)
			&& is_constant_expression(expression->binary.right);

	case EXPR_ERROR:
		return true;
	case EXPR_INVALID:
		break;
	}
	panic("invalid expression in is_constant_expression");
}