X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=68cece384658cf0c6e14ae7824e20a5bf2d17104;hb=8c0dc48b954ccceae0ce547f325d98ce453a5ecf;hp=2f1d07f18cb020c4baab5f548267b9b1b67d933c;hpb=93754445e7b4ef391ac11d2170e56d121f761d2a;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 2f1d07f..68cece3 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -265,7 +265,7 @@ static unsigned get_type_size_const(type_t *type) case TYPE_IMAGINARY: return get_atomic_type_size(type->imaginary.akind); case TYPE_ENUM: - return get_mode_size_bytes(mode_int); + return get_atomic_type_size(type->enumt.akind); case TYPE_COMPOUND_UNION: case TYPE_COMPOUND_STRUCT: return get_compound_type_size(&type->compound); @@ -329,17 +329,30 @@ static unsigned count_parameters(const function_type_t *function_type) return count; } +static type_t *get_aligned_type(type_t *type, int alignment) +{ + if (alignment == 0) + return type; + + type = skip_typeref(type); + if (alignment > type->base.alignment) { + type_t *copy = duplicate_type(type); + copy->base.alignment = alignment; + type = identify_new_type(copy); + } + return type; +} + /** * Creates a Firm type for an atomic type */ -static ir_type *create_atomic_type(const atomic_type_t *type) +static ir_type *create_atomic_type(atomic_type_kind_t akind, int alignment) { - atomic_type_kind_t kind = type->akind; - ir_mode *mode = atomic_modes[kind]; + ir_mode *mode = atomic_modes[akind]; ident *id = get_mode_ident(mode); ir_type *irtype = new_type_primitive(id, mode); - set_type_alignment_bytes(irtype, type->base.alignment); + set_type_alignment_bytes(irtype, alignment); return irtype; } @@ -653,6 +666,8 @@ static ir_type *create_compound_type(compound_type_t *type, ir_type *irtype, symbol_t *symbol = entry->base.symbol; type_t *entry_type = skip_typeref(entry->declaration.type); + entry_type + = get_aligned_type(entry_type, entry->compound_member.alignment); dbg_info *dbgi = get_dbg_info(&entry->base.source_position); ident *ident; @@ -806,7 +821,7 @@ static ir_type *create_enum_type(enum_type_t *const type) constant_folding = constant_folding_old; - return ir_type_int; + return create_atomic_type(type->akind, type->base.alignment); } static ir_type *get_ir_type_incomplete(type_t *type) @@ -846,10 +861,11 @@ ir_type *get_ir_type(type_t *type) switch (type->kind) { case TYPE_ERROR: /* Happens while constant folding, when there was an error */ - return create_atomic_type(&type_void->atomic); + return create_atomic_type(ATOMIC_TYPE_VOID, 0); case TYPE_ATOMIC: - firm_type = create_atomic_type(&type->atomic); + firm_type = create_atomic_type(type->atomic.akind, + type->base.alignment); break; case TYPE_COMPLEX: firm_type = create_complex_type(&type->complex); @@ -1070,12 +1086,8 @@ static ir_entity *get_function_entity(entity_t *entity) if (type->function.linkage != LINKAGE_C) { type_t *new_type = duplicate_type(type); new_type->function.linkage = LINKAGE_C; - - type = typehash_insert(new_type); - if (type != new_type) { - obstack_free(type_obst, new_type); - } - entity->declaration.type = type; + type = identify_new_type(new_type); + entity->declaration.type = type; } } @@ -1359,16 +1371,14 @@ static ir_node *deref_address(dbg_info *const dbgi, type_t *const type, return addr; } + ir_cons_flags flags = type->base.qualifiers & TYPE_QUALIFIER_VOLATILE + ? cons_volatile : 0; ir_mode *const mode = get_type_mode(irtype); ir_node *const memory = get_store(); - ir_node *const load = new_d_Load(dbgi, memory, addr, mode); + ir_node *const load = new_d_Load(dbgi, memory, addr, mode, flags); ir_node *const load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M); ir_node *const load_res = new_d_Proj(dbgi, load, mode, pn_Load_res); - if (type->base.qualifiers & TYPE_QUALIFIER_VOLATILE && !is_Bad(load)) { - set_Load_volatility(load, volatility_is_volatile); - } - set_store(load_mem); ir_mode *const mode_arithmetic = get_ir_mode_arithmetic(type); @@ -1798,10 +1808,10 @@ static void assign_value(dbg_info *dbgi, ir_node *addr, type_t *type, ir_node *memory = get_store(); if (is_type_scalar(type)) { - ir_node *store = new_d_Store(dbgi, memory, addr, value); + ir_cons_flags flags = type->base.qualifiers & TYPE_QUALIFIER_VOLATILE + ? cons_volatile : 0; + ir_node *store = new_d_Store(dbgi, memory, addr, value, flags); ir_node *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M); - if (type->base.qualifiers & TYPE_QUALIFIER_VOLATILE && !is_Bad(store)) - set_Store_volatility(store, volatility_is_volatile); set_store(store_mem); } else { ir_type *irtype = get_ir_type(type); @@ -1856,7 +1866,8 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi, /* load current value */ ir_node *mem = get_store(); - ir_node *load = new_d_Load(dbgi, mem, addr, mode); + ir_node *load = new_d_Load(dbgi, mem, addr, mode, + set_volatile ? cons_volatile : 0); ir_node *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M); ir_node *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res); tarval *shift_mask = create_bitfield_mask(mode, bitoffset, bitsize); @@ -1866,17 +1877,11 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi, /* construct new value and store */ ir_node *new_val = new_d_Or(dbgi, load_res_masked, value_maskshift, mode); - ir_node *store = new_d_Store(dbgi, load_mem, addr, new_val); + ir_node *store = new_d_Store(dbgi, load_mem, addr, new_val, + set_volatile ? cons_volatile : 0); ir_node *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M); set_store(store_mem); - if (set_volatile) { - if (!is_Bad(load)) - set_Load_volatility(load, volatility_is_volatile); - if (!is_Bad(store)) - set_Store_volatility(store, volatility_is_volatile); - } - return value_masked; } @@ -1887,7 +1892,7 @@ static ir_node *bitfield_extract_to_firm(const select_expression_t *expression, type_t *type = expression->base.type; ir_mode *mode = get_ir_mode_storage(type); ir_node *mem = get_store(); - ir_node *load = new_d_Load(dbgi, mem, addr, mode); + ir_node *load = new_d_Load(dbgi, mem, addr, mode, 0); ir_node *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M); ir_node *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res); @@ -2242,12 +2247,11 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression) case EXPR_UNARY_CAST: { ir_node *value_node = expression_to_firm(value); if (is_type_scalar(type)) { - ir_mode *mode = get_ir_mode_storage(type); - ir_node *node = create_conv(dbgi, value_node, mode); - node = do_strict_conv(dbgi, node); - + ir_mode *mode = get_ir_mode_storage(type); + ir_node *node = create_conv(dbgi, value_node, mode); + node = do_strict_conv(dbgi, node); ir_mode *mode_arith = get_ir_mode_arithmetic(type); - node = create_conv(dbgi, node, mode_arith); + node = create_conv(dbgi, node, mode_arith); return node; } else { /* make sure firm type is constructed */ @@ -2258,8 +2262,11 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression) case EXPR_UNARY_CAST_IMPLICIT: { ir_node *value_node = expression_to_firm(value); if (is_type_scalar(type)) { - ir_mode *mode = get_ir_mode_arithmetic(type); - return create_conv(dbgi, value_node, mode); + ir_mode *mode = get_ir_mode_storage(type); + ir_node *res = create_conv(dbgi, value_node, mode); + ir_mode *mode_arith = get_ir_mode_arithmetic(type); + res = create_conv(dbgi, res, mode_arith); + return res; } else { return value_node; } @@ -2472,7 +2479,7 @@ static ir_node *create_lazy_op(const binary_expression_t *expression) } if (is_constant_expression(expression->right)) { - long const valr = fold_constant(expression->left); + long const valr = fold_constant(expression->right); return valr != 0 ? new_Const(get_mode_one(mode)) : new_Const(get_mode_null(mode)); @@ -2492,7 +2499,8 @@ static ir_node *create_assign_binop(const binary_expression_t *expression) { dbg_info *const dbgi = get_dbg_info(&expression->base.source_position); const expression_t *left_expr = expression->left; - ir_mode *left_mode = get_ir_mode_storage(left_expr->base.type); + type_t *type = skip_typeref(left_expr->base.type); + ir_mode *left_mode = get_ir_mode_storage(type); ir_node *right = expression_to_firm(expression->right); ir_node *left_addr = expression_to_addr(left_expr); ir_node *left = get_value_from_lvalue(left_expr, left_addr); @@ -2503,6 +2511,10 @@ static ir_node *create_assign_binop(const binary_expression_t *expression) result = set_value_for_expression_addr(left_expr, result, left_addr); + if (!is_type_compound(type)) { + ir_mode *mode_arithmetic = get_ir_mode_arithmetic(type); + result = create_conv(dbgi, result, mode_arithmetic); + } return result; } @@ -2537,6 +2549,11 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression) ir_node *res = set_value_for_expression_addr(expression->left, right, addr); + type_t *type = skip_typeref(expression->base.type); + if (!is_type_compound(type)) { + ir_mode *mode_arithmetic = get_ir_mode_arithmetic(type); + res = create_conv(NULL, res, mode_arithmetic); + } return res; } case EXPR_BINARY_ADD: @@ -2711,28 +2728,61 @@ static ir_node *sizeof_to_firm(const typeprop_expression_t *expression) return get_type_size(type); } +static entity_t *get_expression_entity(const expression_t *expression) +{ + if (expression->kind != EXPR_REFERENCE) + return NULL; + + return expression->reference.entity; +} + /** * Transform an alignof expression into Firm code. */ static ir_node *alignof_to_firm(const typeprop_expression_t *expression) { - type_t *type = expression->type; - if (type == NULL) { - /* beware: if expression is a variable reference, return the - alignment of the variable. */ - const expression_t *tp_expression = expression->tp_expression; - const entity_t *entity = expression_is_variable(tp_expression); - if (entity != NULL) { - /* TODO: get the alignment of this variable. */ - (void) entity; + ir_entity *irentity = NULL; + + const expression_t *tp_expression = expression->tp_expression; + if (tp_expression != NULL) { + entity_t *entity = get_expression_entity(tp_expression); + if (entity != NULL && is_declaration(entity)) { + switch (entity->declaration.kind) { + case DECLARATION_KIND_UNKNOWN: + panic("unknown entity reference found"); + case DECLARATION_KIND_COMPOUND_MEMBER: + irentity = entity->compound_member.entity; + break; + case DECLARATION_KIND_GLOBAL_VARIABLE: + case DECLARATION_KIND_LOCAL_VARIABLE_ENTITY: + irentity = entity->variable.v.entity; + break; + case DECLARATION_KIND_PARAMETER_ENTITY: + irentity = entity->parameter.v.entity; + break; + case DECLARATION_KIND_FUNCTION: + case DECLARATION_KIND_INNER_FUNCTION: + irentity = entity->function.entity; + break; + case DECLARATION_KIND_PARAMETER: + case DECLARATION_KIND_LOCAL_VARIABLE: + case DECLARATION_KIND_VARIABLE_LENGTH_ARRAY: + break; + } } - type = tp_expression->base.type; - assert(type != NULL); + } + + ir_type *irtype; + if (irentity != NULL) { + irtype = get_entity_type(irentity); + } else { + type_t *type = expression->type; + irtype = get_ir_type(type); } ir_mode *const mode = get_ir_mode_arithmetic(expression->base.type); symconst_symbol sym; - sym.type_p = get_ir_type(type); + sym.type_p = irtype; return new_SymConst(mode, sym, symconst_type_align); } @@ -2750,9 +2800,7 @@ long fold_constant(const expression_t *expression) assert(is_constant_expression(expression)); ir_graph *old_current_ir_graph = current_ir_graph; - if (current_ir_graph == NULL) { - current_ir_graph = get_const_code_irg(); - } + current_ir_graph = get_const_code_irg(); ir_node *cnst = expression_to_firm(expression); current_ir_graph = old_current_ir_graph; @@ -3365,7 +3413,7 @@ static ir_node *create_condition_evaluation(const expression_t *expression, 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)) { + if (is_builtin_expect(expression) && is_Cond(cond)) { call_argument_t *argument = expression->call.arguments->next; if (is_constant_expression(argument->expression)) { long cnst = fold_constant(argument->expression); @@ -3393,10 +3441,13 @@ static void create_variable_entity(entity_t *variable, ir_type *parent_type) { assert(variable->kind == ENTITY_VARIABLE); - type_t *const type = skip_typeref(variable->declaration.type); + type_t *type = skip_typeref(variable->declaration.type); + type = get_aligned_type(type, variable->variable.alignment); + ident *const id = new_id_from_str(variable->base.symbol->string); ir_type *const irtype = get_ir_type(type); dbg_info *const dbgi = get_dbg_info(&variable->base.source_position); + ir_entity *const irentity = new_d_entity(parent_type, id, irtype, dbgi); handle_gnu_attributes_ent(irentity, variable); @@ -3405,6 +3456,7 @@ static void create_variable_entity(entity_t *variable, variable->variable.v.entity = irentity; set_entity_variability(irentity, variability_uninitialized); set_entity_ld_ident(irentity, create_ld_ident(variable)); + if (parent_type == get_tls_type()) set_entity_allocation(irentity, allocation_automatic); else if (declaration_kind == DECLARATION_KIND_GLOBAL_VARIABLE) @@ -3839,7 +3891,7 @@ static void create_dynamic_null_initializer(ir_type *type, dbg_info *dbgi, /* TODO: bitfields */ ir_node *mem = get_store(); - ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst); + ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst, 0); ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M); set_store(proj_m); } else { @@ -3897,7 +3949,7 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer, assert(get_type_mode(type) == mode); ir_node *mem = get_store(); - ir_node *store = new_d_Store(dbgi, mem, base_addr, node); + ir_node *store = new_d_Store(dbgi, mem, base_addr, node, 0); ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M); set_store(proj_m); return; @@ -3917,7 +3969,7 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer, assert(get_type_mode(type) == mode); ir_node *mem = get_store(); - ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst); + ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst, 0); ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M); set_store(proj_m); return; @@ -4039,6 +4091,8 @@ static void create_initializer_local_variable_entity(entity_t *entity) dbg_info *dbgi = get_dbg_info(&entity->base.source_position); ir_entity *irentity = entity->variable.v.entity; type_t *type = entity->declaration.type; + + type = get_aligned_type(type, entity->variable.alignment); create_local_initializer(initializer, dbgi, irentity, type); } @@ -4177,7 +4231,9 @@ static void create_local_static_variable(entity_t *entity) assert(entity->kind == ENTITY_VARIABLE); assert(entity->declaration.kind == DECLARATION_KIND_UNKNOWN); - type_t *const type = skip_typeref(entity->declaration.type); + type_t *type = skip_typeref(entity->declaration.type); + type = get_aligned_type(type, entity->variable.alignment); + ir_type *const var_type = entity->variable.thread_local ? get_tls_type() : get_glob_type(); ir_type *const irtype = get_ir_type(type); @@ -4196,6 +4252,7 @@ static void create_local_static_variable(entity_t *entity) entity->declaration.kind = DECLARATION_KIND_GLOBAL_VARIABLE; entity->variable.v.entity = irentity; + set_entity_ld_ident(irentity, id); set_entity_variability(irentity, variability_uninitialized); set_entity_visibility(irentity, visibility_local); @@ -4401,7 +4458,7 @@ static void declaration_statement_to_firm(declaration_statement_t *statement) if (is_declaration(entity)) { initialize_local_declaration(entity); } else if (entity->kind == ENTITY_TYPEDEF) { - type_t *const type = entity->typedefe.type; + type_t *const type = skip_typeref(entity->typedefe.type); if (is_type_array(type) && type->array.is_vla) get_vla_size(&type->array); }