type_t *type = expression->type;
initializer_t *initializer = expression->initializer;
- if (is_constant_initializer(initializer) == EXPR_CLASS_CONSTANT) {
+ if (expression->global_scope ||
+ ((type->base.qualifiers & TYPE_QUALIFIER_CONST)
+ && is_constant_initializer(initializer) == EXPR_CLASS_CONSTANT)) {
ir_entity *entity = create_initializer_entity(dbgi, initializer, type);
return create_symconst(dbgi, entity);
} else {
static ir_node *conditional_to_firm(const conditional_expression_t *expression)
{
- dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
-
/* first try to fold a constant condition */
if (is_constant_expression(expression->condition) == EXPR_CLASS_CONSTANT) {
bool val = fold_constant_to_bool(expression->condition);
ir_node *const false_val = expression_to_firm(expression->false_expression);
jump_to_target(&exit_target);
if (val) {
- ir_node *const in[] = { val, false_val };
+ ir_node *const in[] = { val, false_val };
+ dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
val = new_rd_Phi(dbgi, exit_target.block, lengthof(in), in, get_irn_mode(val));
} else {
val = false_val;
break;
}
- dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
- ir_node *cond_expr = _expression_to_firm(expression);
- ir_node *condition = create_conv(dbgi, cond_expr, mode_b);
- ir_node *cond = new_d_Cond(dbgi, condition);
- ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
- ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false);
-
- /* set branch prediction info based on __builtin_expect */
- if (is_builtin_expect(expression) && is_Cond(cond)) {
- call_argument_t *argument = expression->call.arguments->next;
- if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
- bool const cnst = fold_constant_to_bool(argument->expression);
- cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
- set_Cond_jmp_pred(cond, pred);
+ ir_node *cond_expr = _expression_to_firm(expression);
+ if (is_Const(cond_expr)) {
+ if (tarval_is_null(get_Const_tarval(cond_expr))) {
+ jump_to_target(false_target);
+ } else {
+ jump_to_target(true_target);
+ }
+ } else {
+ dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+ ir_node *condition = create_conv(dbgi, cond_expr, mode_b);
+ ir_node *cond = new_d_Cond(dbgi, condition);
+ ir_node *true_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
+ ir_node *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false);
+
+ /* set branch prediction info based on __builtin_expect */
+ if (is_builtin_expect(expression) && is_Cond(cond)) {
+ call_argument_t *argument = expression->call.arguments->next;
+ if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
+ bool const cnst = fold_constant_to_bool(argument->expression);
+ cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
+ set_Cond_jmp_pred(cond, pred);
+ }
}
- }
-
- add_pred_to_jump_target(true_target, true_proj);
- add_pred_to_jump_target(false_target, false_proj);
+ add_pred_to_jump_target(true_target, true_proj);
+ add_pred_to_jump_target(false_target, false_proj);
+ }
set_unreachable_now();
return cond_expr;
}
static ir_initializer_t *create_ir_initializer_value(
const initializer_value_t *initializer)
{
- if (is_type_compound(initializer->value->base.type)) {
- panic("initializer creation for compounds not implemented yet");
- }
- type_t *type = initializer->value->base.type;
expression_t *expr = initializer->value;
+ type_t *type = skip_typeref(expr->base.type);
+
+ if (is_type_compound(type)) {
+ if (expr->kind == EXPR_UNARY_CAST) {
+ expr = expr->unary.value;
+ type = skip_typeref(expr->base.type);
+ }
+ /* must be a compound literal... */
+ if (expr->kind == EXPR_COMPOUND_LITERAL) {
+ return create_ir_initializer(expr->compound_literal.initializer,
+ type);
+ }
+ }
+
ir_node *value = expression_to_firm(expr);
- ir_mode *mode = get_ir_mode_storage(type);
- value = create_conv(NULL, value, mode);
+ if (!is_type_compound(type)) {
+ ir_mode *mode = get_ir_mode_storage(type);
+ value = create_conv(NULL, value, mode);
+ }
return create_initializer_const(value);
}
}
if (sub_initializer->kind == INITIALIZER_VALUE) {
- /* we might have to descend into types until we're at a scalar
- * type */
+ const expression_t *expr = sub_initializer->value.value;
+ const type_t *expr_type = skip_typeref(expr->base.type);
+ /* we might have to descend into types until the types match */
while(true) {
type_t *orig_top_type = path.top_type;
type_t *top_type = skip_typeref(orig_top_type);
- if (is_type_scalar(top_type))
+ if (types_compatible(top_type, expr_type))
break;
descend_into_subtype(&path);
}
return;
}
- assert(get_type_mode(type) == get_irn_mode(node));
- ir_node *mem = get_store();
- ir_node *store = new_d_Store(dbgi, mem, base_addr, node, cons_none);
- ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
- set_store(proj_m);
+ ir_node *mem = get_store();
+ ir_node *new_mem;
+ if (is_compound_type(ent_type)) {
+ ir_node *copyb = new_d_CopyB(dbgi, mem, base_addr, node, ent_type);
+ new_mem = new_Proj(copyb, mode_M, pn_CopyB_M);
+ } else {
+ assert(get_type_mode(type) == get_irn_mode(node));
+ ir_node *store = new_d_Store(dbgi, mem, base_addr, node, cons_none);
+ new_mem = new_Proj(store, mode_M, pn_Store_M);
+ }
+ set_store(new_mem);
return;
}
case IR_INITIALIZER_TARVAL: {
}
if (enter_jump_target(&ijmp_target)) {
+ keep_loop();
size_t const n = ARR_LEN(ijmp_ops);
ir_node *const op = n == 1 ? ijmp_ops[0] : new_Phi(n, ijmp_ops, get_irn_mode(ijmp_ops[0]));
ir_node *const ijmp = new_IJmp(op);