X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=7211342d2d29fbeeee2823e38fa0868c89dff647;hb=da347dbcaaa48cd4f9082bf0f25e980190ffb269;hp=a042ccac7e77150fcc2e3ac20192f74773fa9b2b;hpb=7af4fd40936ea5b3647c901c4b5f6957d7580aaa;p=cparser diff --git a/ast2firm.c b/ast2firm.c index a042cca..7211342 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -133,10 +133,10 @@ static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind) if( (flags & (ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_FLOAT)) && !(flags & ATOMIC_TYPE_FLAG_COMPLEX)) { char name[64]; - mode_sort sort; + ir_mode_sort sort; unsigned bit_size = size * 8; bool is_signed = (flags & ATOMIC_TYPE_FLAG_SIGNED) != 0; - mode_arithmetic arithmetic; + ir_mode_arithmetic arithmetic; unsigned modulo_shift; if(flags & ATOMIC_TYPE_FLAG_INTEGER) { @@ -175,10 +175,10 @@ static void init_atomic_modes(void) /* initialize pointer modes */ char name[64]; - mode_sort sort = irms_reference; + ir_mode_sort sort = irms_reference; unsigned bit_size = machine_size; bool is_signed = 0; - mode_arithmetic arithmetic = irma_twos_complement; + ir_mode_arithmetic arithmetic = irma_twos_complement; unsigned modulo_shift = bit_size < machine_size ? machine_size : bit_size; @@ -814,8 +814,6 @@ static inline ir_mode *get_ir_mode(type_t *type) return mode; } -static ident *predef_idents[rts_max]; - /** Names of the runtime functions. */ static const struct { int id; /**< the rts id */ @@ -826,6 +824,7 @@ static const struct { } rts_data[] = { { rts_debugbreak, 0, "__debugbreak", 0, _MS }, { rts_abort, 0, "abort", 0, _C89 }, + { rts_alloca, 1, "alloca", 1, _GNUC }, { rts_abs, 1, "abs", 1, _C89 }, { rts_labs, 1, "labs", 1, _C89 }, { rts_llabs, 1, "llabs", 1, _C99 }, @@ -897,6 +896,8 @@ static const struct { { rts_strncmp, 1, "strncmp", 3, _C89 } }; +static ident *rts_idents[sizeof(rts_data) / sizeof(rts_data[0])]; + /** * Mangles an entity linker (ld) name for win32 usage. * @@ -980,36 +981,27 @@ static ir_entity* get_function_entity(declaration_t *declaration) set_entity_visibility(entity, visibility_external_visible); } else { set_entity_visibility(entity, visibility_external_allocated); - - /* We should check for file scope here, but as long as we compile C only - this is not needed. */ - int n_params = get_method_n_params(ir_type_method); - int n_res = get_method_n_ress(ir_type_method); - int i; - - if (n_params == 0 && n_res == 0 && id == predef_idents[rts_abort]) { - /* found abort(), store for later */ - //abort_ent = ent; - //abort_tp = ftype; - } else { - if (! firm_opt.freestanding) { - /* check for a known runtime function */ - for (i = 0; i < rts_max; ++i) { - /* ignore those rts functions not necessary needed for current mode */ - if ((c_mode & rts_data[i].flags) == 0) - continue; - if (n_params == rts_data[i].n_params && n_res == rts_data[i].n_res && - id == predef_idents[rts_data[i].id]) - rts_entities[rts_data[i].id] = entity; - } - } - } } set_entity_allocation(entity, allocation_static); declaration->declaration_kind = DECLARATION_KIND_FUNCTION; declaration->v.entity = entity; + /* We should check for file scope here, but as long as we compile C only + this is not needed. */ + if (! firm_opt.freestanding) { + /* check for a known runtime function */ + for (size_t i = 0; i < sizeof(rts_data) / sizeof(rts_data[0]); ++i) { + if (id != rts_idents[i]) + continue; + + /* ignore those rts functions not necessary needed for current mode */ + if ((c_mode & rts_data[i].flags) == 0) + continue; + rts_entities[rts_data[i].id] = entity; + } + } + return entity; } @@ -1237,6 +1229,23 @@ static ir_node *get_local_frame(ir_entity *const ent) } } +static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode) +{ + ir_mode *value_mode = get_irn_mode(value); + + if (value_mode == dest_mode || is_Bad(value)) + return value; + + if(dest_mode == mode_b) { + ir_node *zero = new_Const(value_mode, get_mode_null(value_mode)); + ir_node *cmp = new_d_Cmp(dbgi, value, zero); + ir_node *proj = new_d_Proj(dbgi, cmp, mode_b, pn_Cmp_Lg); + return proj; + } + + return new_d_Conv(dbgi, value, dest_mode); +} + static ir_node *reference_expression_to_firm(const reference_expression_t *ref) { dbg_info *dbgi = get_dbg_info(&ref->base.source_position); @@ -1362,6 +1371,12 @@ static ir_node *process_builtin_call(const call_expression_t *call) return res; } + case T___builtin_huge_val: { + ir_mode *mode = get_ir_mode(function_type->function.return_type); + tarval *tv = get_mode_infinite(mode); + ir_node *res = new_d_Const(dbgi, mode, tv); + return res; + } case T___builtin_nan: case T___builtin_nanf: case T___builtin_nand: { @@ -1396,23 +1411,23 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) assert(is_type_function(points_to)); function_type_t *function_type = &points_to->function; - int n_parameters = 0; - call_argument_t *argument = call->arguments; - for( ; argument != NULL; argument = argument->next) { - ++n_parameters; - } - dbg_info *dbgi = get_dbg_info(&call->base.source_position); + int n_parameters = 0; ir_type *ir_method_type = get_ir_type((type_t*) function_type); ir_type *new_method_type = NULL; if(function_type->variadic || function_type->unspecified_parameters) { + const call_argument_t *argument = call->arguments; + for( ; argument != NULL; argument = argument->next) { + ++n_parameters; + } + /* we need to construct a new method type matching the call * arguments... */ int n_res = get_method_n_ress(ir_method_type); dbg_info *dbgi = get_dbg_info(&call->base.source_position); new_method_type = new_d_type_method(id_unique("calltype.%u"), - n_parameters, n_res, dbgi); + n_parameters, n_res, dbgi); set_method_calling_convention(new_method_type, get_method_calling_convention(ir_method_type)); set_method_additional_properties(new_method_type, @@ -1424,29 +1439,30 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) set_method_res_type(new_method_type, i, get_method_res_type(ir_method_type, i)); } + argument = call->arguments; + for(int i = 0; i < n_parameters; ++i, argument = argument->next) { + expression_t *expression = argument->expression; + ir_type *irtype = get_ir_type(expression->base.type); + set_method_param_type(new_method_type, i, irtype); + } + ir_method_type = new_method_type; + } else { + n_parameters = get_method_n_params(ir_method_type); } + ir_node *in[n_parameters]; - argument = call->arguments; - int n = 0; - for( ; argument != NULL; argument = argument->next) { + const call_argument_t *argument = call->arguments; + for(int n = 0; n < n_parameters; ++n) { expression_t *expression = argument->expression; ir_node *arg_node = expression_to_firm(expression); arg_node = do_strict_conv(dbgi, arg_node); in[n] = arg_node; - if(new_method_type != NULL) { - ir_type *irtype = get_ir_type(expression->base.type); - set_method_param_type(new_method_type, n, irtype); - } - n++; + argument = argument->next; } - assert(n == n_parameters); - - if(new_method_type != NULL) - ir_method_type = new_method_type; ir_node *store = get_store(); ir_node *node = new_d_Call(dbgi, store, callee, n_parameters, in, @@ -1531,7 +1547,7 @@ static void bitfield_store_to_firm(const unary_expression_t *expression, ir_mode *mode = get_ir_mode(type->bitfield.base_type); ir_node *addr = expression_to_addr(select); - assert(get_irn_mode(value) == mode); + assert(get_irn_mode(value) == mode || is_Bad(value)); dbg_info *dbgi = get_dbg_info(&expression->base.source_position); @@ -1597,23 +1613,6 @@ static void set_value_for_expression(const expression_t *expression, assign_value(dbgi, addr, type, value); } -static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode) -{ - ir_mode *value_mode = get_irn_mode(value); - - if (value_mode == dest_mode || is_Bad(value)) - return value; - - if(dest_mode == mode_b) { - ir_node *zero = new_Const(value_mode, get_mode_null(value_mode)); - ir_node *cmp = new_d_Cmp(dbgi, value, zero); - ir_node *proj = new_d_Proj(dbgi, cmp, mode_b, pn_Cmp_Lg); - return proj; - } - - return new_d_Conv(dbgi, value, dest_mode); -} - static ir_node *create_incdec(const unary_expression_t *expression) { dbg_info *dbgi = get_dbg_info(&expression->base.source_position); @@ -2264,15 +2263,22 @@ static ir_node *array_access_addr(const array_access_expression_t *expression) dbg_info *dbgi = get_dbg_info(&expression->base.source_position); ir_node *base_addr = expression_to_firm(expression->array_ref); ir_node *offset = expression_to_firm(expression->index); - offset = create_conv(dbgi, offset, mode_uint); + + /* Matze: it would be better to force mode to mode_uint as this creates more + * opportunities for CSE. Unforunately we still have some optimisations that + * are too conservative in the presence of convs. So we better go with the + * mode of offset and avoid the conv */ + ir_mode *mode = get_irn_mode(offset); + offset = create_conv(dbgi, offset, mode); type_t *ref_type = skip_typeref(expression->array_ref->base.type); assert(is_type_pointer(ref_type)); pointer_type_t *pointer_type = &ref_type->pointer; ir_node *elem_size_const = get_type_size(pointer_type->points_to); + elem_size_const = create_conv(dbgi, elem_size_const, mode); ir_node *real_offset = new_d_Mul(dbgi, offset, elem_size_const, - mode_uint); + mode); ir_node *result = new_d_Add(dbgi, base_addr, real_offset, mode_P_data); return result; @@ -3625,9 +3631,14 @@ static void create_local_static_variable(declaration_t *declaration) type_t *const type = skip_typeref(declaration->type); ir_type *const global_type = get_glob_type(); - ident *const id = new_id_from_str(declaration->symbol->string); ir_type *const irtype = get_ir_type(type); dbg_info *const dbgi = get_dbg_info(&declaration->source_position); + + size_t l = strlen(declaration->symbol->string); + char buf[l + sizeof(".%u")]; + snprintf(buf, sizeof(buf), "%s.%%u", declaration->symbol->string); + ident *const id = id_unique(buf); + ir_entity *const entity = new_d_entity(global_type, id, irtype, dbgi); if(type->base.qualifiers & TYPE_QUALIFIER_VOLATILE) { @@ -4087,6 +4098,7 @@ static void switch_statement_to_firm(const switch_statement_t *statement) ir_node *const old_switch_cond = current_switch_cond; ir_node *const old_break_label = break_label; const bool old_saw_default_label = saw_default_label; + saw_default_label = false; current_switch_cond = cond; break_label = break_block; @@ -4877,7 +4889,7 @@ void init_ast2firm(void) /* create idents for all known runtime functions */ for (size_t i = 0; i < sizeof(rts_data) / sizeof(rts_data[0]); ++i) { - predef_idents[rts_data[i].id] = new_id_from_str(rts_data[i].name); + rts_idents[i] = new_id_from_str(rts_data[i].name); } }