X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ast2firm.c;h=43e7deb691b39f6cba2c8ae056137fd324c3d135;hb=296ba6e16420b89723d1a5b1217d6ecfc2fb0c7d;hp=18283b84e0540c1b053a4b80857c617821f52472;hpb=47143e8e0c7b1da7d1e155a5776ce1d5d68c51ea;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 18283b8..43e7deb 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -76,9 +76,9 @@ static ir_node *continue_label; static ir_node *break_label; static ir_node *current_switch; static bool saw_default_label; -static label_t **all_labels; static entity_t **inner_functions; static ir_node *ijmp_list; +static ir_node **ijmp_blocks; static bool constant_folding; #define PUSH_BREAK(val) \ @@ -625,9 +625,7 @@ static ir_type *create_compound_type(compound_type_t *const type, bool const inc return irtype; } -static ir_tarval *fold_constant_to_tarval(expression_t const *); - -static void determine_enum_values(enum_type_t *const type) +void determine_enum_values(enum_type_t *const type) { ir_mode *const mode = atomic_modes[type->base.akind]; ir_tarval *const one = get_mode_one(mode); @@ -899,12 +897,19 @@ static void handle_decl_modifiers(ir_entity *irentity, entity_t *entity) decl_modifiers_t modifiers = entity->declaration.modifiers; if (is_method_entity(irentity)) { - if (modifiers & DM_PURE) { - set_entity_additional_properties(irentity, mtp_property_pure); - } - if (modifiers & DM_CONST) { + if (modifiers & DM_PURE) + add_entity_additional_properties(irentity, mtp_property_pure); + if (modifiers & DM_CONST) add_entity_additional_properties(irentity, mtp_property_const); - } + if (modifiers & DM_NOINLINE) + add_entity_additional_properties(irentity, mtp_property_noinline); + if (modifiers & DM_FORCEINLINE) + add_entity_additional_properties(irentity, mtp_property_always_inline); + if (modifiers & DM_NAKED) + add_entity_additional_properties(irentity, mtp_property_naked); + if (entity->kind == ENTITY_FUNCTION && entity->function.is_inline) + add_entity_additional_properties(irentity, + mtp_property_inline_recommended); } if ((modifiers & DM_USED) && declaration_is_definition(entity)) { add_entity_linkage(irentity, IR_LINKAGE_HIDDEN_USER); @@ -2836,7 +2841,7 @@ static ir_node *alignof_to_firm(const typeprop_expression_t *expression) static void init_ir_types(void); -static ir_tarval *fold_constant_to_tarval(const expression_t *expression) +ir_tarval *fold_constant_to_tarval(const expression_t *expression) { assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT); @@ -3234,8 +3239,8 @@ static ir_node *get_label_block(label_t *label) ir_node *block = new_immBlock(); label->block = block; - - ARR_APP1(label_t *, all_labels, label); + if (label->address_taken) + ARR_APP1(ir_node*, ijmp_blocks, block); return block; } @@ -4681,11 +4686,9 @@ static ir_switch_table *create_switch_table(const switch_statement_t *statement) } if (l->is_empty_range) continue; - ir_tarval *min = fold_constant_to_tarval(l->expression); - ir_tarval *max = min; + ir_tarval *min = l->first_case; + ir_tarval *max = l->last_case; long pn = (long) i+1; - if (l->end_range != NULL) - max = fold_constant_to_tarval(l->end_range); ir_switch_table_set(res, i++, min, max, pn); l->pn = pn; } @@ -4738,10 +4741,7 @@ static ir_node *switch_statement_to_firm(switch_statement_t *statement) static ir_node *case_label_to_firm(const case_label_statement_t *statement) { - if (statement->is_empty_range) - return NULL; - - if (current_switch != NULL) { + if (current_switch != NULL && !statement->is_empty_range) { ir_node *block = new_immBlock(); /* Fallthrough from previous case */ jump_if_reachable(block); @@ -4758,17 +4758,34 @@ static ir_node *case_label_to_firm(const case_label_statement_t *statement) return statement_to_firm(statement->statement); } +static void try_mature_label(label_t *const label) +{ + if (--label->n_users == 0 && !label->address_taken) + mature_immBlock(label->block); +} + static ir_node *label_to_firm(const label_statement_t *statement) { - ir_node *block = get_label_block(statement->label); + label_t *const label = statement->label; + ir_node *const block = get_label_block(label); jump_to(block); keep_alive(block); keep_all_memory(block); + try_mature_label(label); + return statement_to_firm(statement->statement); } +static ir_node *goto_statement_to_firm(goto_statement_t *const stmt) +{ + label_t *const label = stmt->label; + create_jump_statement((statement_t*)stmt, get_label_block(label)); + try_mature_label(label); + return NULL; +} + static ir_node *computed_goto_to_firm(computed_goto_statement_t const *const statement) { if (!currently_reachable()) @@ -5049,6 +5066,7 @@ static ir_node *statement_to_firm(statement_t *const stmt) case STATEMENT_EMPTY: return NULL; /* nothing */ case STATEMENT_EXPRESSION: return expression_statement_to_firm( &stmt->expression); case STATEMENT_FOR: return for_statement_to_firm( &stmt->fors); + case STATEMENT_GOTO: return goto_statement_to_firm( &stmt->gotos); case STATEMENT_IF: return if_statement_to_firm( &stmt->ifs); case STATEMENT_LABEL: return label_to_firm( &stmt->label); case STATEMENT_LEAVE: return leave_statement_to_firm( &stmt->leave); @@ -5058,7 +5076,6 @@ static ir_node *statement_to_firm(statement_t *const stmt) case STATEMENT_BREAK: return create_jump_statement(stmt, get_break_label()); case STATEMENT_CONTINUE: return create_jump_statement(stmt, continue_label); - case STATEMENT_GOTO: return create_jump_statement(stmt, get_label_block(stmt->gotos.label)); case STATEMENT_ERROR: panic("error statement found"); } @@ -5176,32 +5193,6 @@ static void initialize_function_parameters(entity_t *entity) } } -/** - * Handle additional decl modifiers for IR-graphs - * - * @param irg the IR-graph - * @param dec_modifiers additional modifiers - */ -static void handle_decl_modifier_irg(ir_graph *irg, - decl_modifiers_t decl_modifiers) -{ - if (decl_modifiers & DM_NAKED) { - /* TRUE if the declaration includes the Microsoft - __declspec(naked) specifier. */ - add_irg_additional_properties(irg, mtp_property_naked); - } - if (decl_modifiers & DM_FORCEINLINE) { - /* TRUE if the declaration includes the - Microsoft __forceinline specifier. */ - set_irg_inline_property(irg, irg_inline_forced); - } - if (decl_modifiers & DM_NOINLINE) { - /* TRUE if the declaration includes the Microsoft - __declspec(noinline) specifier. */ - set_irg_inline_property(irg, irg_inline_forbidden); - } -} - static void add_function_pointer(ir_type *segment, ir_entity *method, const char *unique_template) { @@ -5265,9 +5256,9 @@ static void create_function(entity_t *entity) current_function_name = NULL; current_funcsig = NULL; - assert(all_labels == NULL); - all_labels = NEW_ARR_F(label_t *, 0); - ijmp_list = NULL; + assert(ijmp_blocks == NULL); + ijmp_blocks = NEW_ARR_F(ir_node*, 0); + ijmp_list = NULL; int n_local_vars = get_function_n_local_vars(entity); ir_graph *irg = new_ir_graph(function_entity, n_local_vars); @@ -5284,11 +5275,6 @@ static void create_function(entity_t *entity) set_irn_dbg_info(get_irg_start_block(irg), get_entity_dbg_info(function_entity)); - /* set inline flags */ - if (entity->function.is_inline) - set_irg_inline_property(irg, irg_inline_recomended); - handle_decl_modifier_irg(irg, entity->declaration.modifiers); - next_value_number_function = 0; initialize_function_parameters(entity); current_static_link = entity->function.static_link; @@ -5321,16 +5307,14 @@ static void create_function(entity_t *entity) add_immBlock_pred(end_block, ret); } - for (int i = ARR_LEN(all_labels) - 1; i >= 0; --i) { - label_t *label = all_labels[i]; - if (label->address_taken) { - gen_ijmp_branches(label->block); - } - mature_immBlock(label->block); + for (size_t i = ARR_LEN(ijmp_blocks); i-- != 0;) { + ir_node *const block = ijmp_blocks[i]; + gen_ijmp_branches(block); + mature_immBlock(block); } - DEL_ARR_F(all_labels); - all_labels = NULL; + DEL_ARR_F(ijmp_blocks); + ijmp_blocks = NULL; irg_finalize_cons(irg);