X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ast2firm.c;h=50ab3254d961a325a6d0824beb53dca0b5afba35;hb=fbbb2b6932bdd8455b850b750d93b4d5584402a7;hp=1f82c559c6ab1d9c0c5449b6073a272e05f59081;hpb=01255012750ab09ae01827758e3eee34a537efd3;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 1f82c55..50ab325 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -133,7 +133,7 @@ static ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos) { const entity_t *entity = get_irg_loc_description(irg, pos); - if (entity != NULL) { + if (entity != NULL && warning.uninitialized) { warningf(&entity->base.source_position, "%s '%#T' might be used uninitialized", get_entity_kind_name(entity->kind), @@ -1089,14 +1089,18 @@ static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode) if (dest_mode == mode_b) { ir_node *zero = new_Const(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; + ir_node *cmp = new_d_Cmp(dbgi, value, zero, ir_relation_less_greater); + return cmp; } return new_d_Conv(dbgi, value, dest_mode); } +static ir_node *create_Const_from_bool(ir_mode *const mode, bool const v) +{ + return new_Const((v ? get_mode_one : get_mode_null)(mode)); +} + /** * Creates a SymConst node representing a wide string literal. * @@ -1565,7 +1569,7 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref) /* simply create a NULL pointer */ ir_mode *mode = get_ir_mode_arithmetic(type_void_ptr); - ir_node *res = new_Const_long(mode, 0); + ir_node *res = new_Const(get_mode_null(mode)); return res; } @@ -1890,13 +1894,9 @@ static ir_node *process_builtin_call(const call_expression_t *call) long type_val = fold_constant_to_int(type_expression); type_t *type = function_type->function.return_type; ir_mode *mode = get_ir_mode_arithmetic(type); - ir_tarval *result; - /* just produce a "I don't know" result */ - if (type_val & 2) - result = new_tarval_from_long(0, mode); - else - result = new_tarval_from_long(-1, mode); + ir_tarval *result = type_val & 2 ? get_mode_null(mode) : + get_mode_minus_one(mode); return new_d_Const(dbgi, result); } @@ -1917,7 +1917,7 @@ static ir_node *process_builtin_call(const call_expression_t *call) case bk_ms_ReturnAddress: { ir_node *in[2]; - in[0] = new_Const_long(mode_int, 0); + in[0] = new_Const(get_mode_null(mode_int)); in[1] = get_irg_frame(current_ir_graph); ir_type *tp = get_ir_type(function_type); ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_return_address, tp); @@ -2413,22 +2413,21 @@ static bool is_local_variable(expression_t *expression) return entity->declaration.kind == DECLARATION_KIND_LOCAL_VARIABLE; } -static pn_Cmp get_pnc(const expression_kind_t kind, type_t *const type) +static ir_relation get_relation(const expression_kind_t kind) { switch(kind) { - case EXPR_BINARY_EQUAL: return pn_Cmp_Eq; - case EXPR_BINARY_ISLESSGREATER: return pn_Cmp_Lg; - case EXPR_BINARY_NOTEQUAL: - return is_type_float(skip_typeref(type)) ? pn_Cmp_Ne : pn_Cmp_Lg; + case EXPR_BINARY_EQUAL: return ir_relation_equal; + case EXPR_BINARY_ISLESSGREATER: return ir_relation_less_greater; + case EXPR_BINARY_NOTEQUAL: return ir_relation_unordered_less_greater; case EXPR_BINARY_ISLESS: - case EXPR_BINARY_LESS: return pn_Cmp_Lt; + case EXPR_BINARY_LESS: return ir_relation_less; case EXPR_BINARY_ISLESSEQUAL: - case EXPR_BINARY_LESSEQUAL: return pn_Cmp_Le; + case EXPR_BINARY_LESSEQUAL: return ir_relation_less_equal; case EXPR_BINARY_ISGREATER: - case EXPR_BINARY_GREATER: return pn_Cmp_Gt; + case EXPR_BINARY_GREATER: return ir_relation_greater; case EXPR_BINARY_ISGREATEREQUAL: - case EXPR_BINARY_GREATEREQUAL: return pn_Cmp_Ge; - case EXPR_BINARY_ISUNORDERED: return pn_Cmp_Uo; + case EXPR_BINARY_GREATEREQUAL: return ir_relation_greater_equal; + case EXPR_BINARY_ISUNORDERED: return ir_relation_unordered; default: break; @@ -2454,10 +2453,8 @@ static ir_node *handle_assume_compare(dbg_info *dbi, expression_t *op1 = expression->left; expression_t *op2 = expression->right; entity_t *var2, *var = NULL; - ir_node *res = NULL; - pn_Cmp cmp_val; - - cmp_val = get_pnc(expression->base.kind, op1->base.type); + ir_node *res = NULL; + ir_relation relation = get_relation(expression->base.kind); if (is_local_variable(op1) && is_local_variable(op2)) { var = op1->reference.entity; @@ -2469,21 +2466,21 @@ static ir_node *handle_assume_compare(dbg_info *dbi, ir_node *const irn1 = get_value(var->variable.v.value_number, mode); ir_node *const irn2 = get_value(var2->variable.v.value_number, mode); - res = new_d_Confirm(dbi, irn2, irn1, get_inversed_pnc(cmp_val)); + res = new_d_Confirm(dbi, irn2, irn1, get_inversed_relation(relation)); set_value(var2->variable.v.value_number, res); - res = new_d_Confirm(dbi, irn1, irn2, cmp_val); + res = new_d_Confirm(dbi, irn1, irn2, relation); set_value(var->variable.v.value_number, res); return res; } expression_t *con; - if (is_local_variable(op1) && is_constant_expression(op2)) { + if (is_local_variable(op1) && is_constant_expression(op2) == EXPR_CLASS_CONSTANT) { var = op1->reference.entity; con = op2; - } else if (is_constant_expression(op1) && is_local_variable(op2)) { - cmp_val = get_inversed_pnc(cmp_val); + } else if (is_constant_expression(op1) == EXPR_CLASS_CONSTANT && is_local_variable(op2)) { + relation = get_inversed_relation(relation); var = op2->reference.entity; con = op1; } @@ -2493,7 +2490,7 @@ static ir_node *handle_assume_compare(dbg_info *dbi, ir_mode *const mode = get_ir_mode_storage(type); res = get_value(var->variable.v.value_number, mode); - res = new_d_Confirm(dbi, res, expression_to_firm(con), cmp_val); + res = new_d_Confirm(dbi, res, expression_to_firm(con), relation); set_value(var->variable.v.value_number, res); } return res; @@ -2520,7 +2517,7 @@ static ir_node *handle_assume(dbg_info *dbi, const expression_t *expression) } } -static ir_node *create_cast(dbg_info *dbgi, ir_node *value_node, +static ir_node *create_cast(dbg_info *dbgi, ir_node *value_node, type_t *from_type, type_t *type) { type = skip_typeref(type); @@ -2639,29 +2636,22 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression) static ir_node *produce_condition_result(const expression_t *expression, ir_mode *mode, dbg_info *dbgi) { - ir_node *cur_block = get_cur_block(); - - ir_node *one_block = new_immBlock(); - set_cur_block(one_block); - ir_node *one = new_Const(get_mode_one(mode)); - ir_node *jmp_one = new_d_Jmp(dbgi); - - ir_node *zero_block = new_immBlock(); - set_cur_block(zero_block); - ir_node *zero = new_Const(get_mode_null(mode)); - ir_node *jmp_zero = new_d_Jmp(dbgi); - - set_cur_block(cur_block); + ir_node *const one_block = new_immBlock(); + ir_node *const zero_block = new_immBlock(); create_condition_evaluation(expression, one_block, zero_block); mature_immBlock(one_block); mature_immBlock(zero_block); - ir_node *in_cf[2] = { jmp_one, jmp_zero }; - ir_node *block = new_Block(2, in_cf); + ir_node *const jmp_one = new_rd_Jmp(dbgi, one_block); + ir_node *const jmp_zero = new_rd_Jmp(dbgi, zero_block); + ir_node *const in_cf[2] = { jmp_one, jmp_zero }; + ir_node *const block = new_Block(lengthof(in_cf), in_cf); set_cur_block(block); - ir_node *in[2] = { one, zero }; - ir_node *val = new_d_Phi(dbgi, 2, in, mode); + ir_node *const one = new_Const(get_mode_one(mode)); + ir_node *const zero = new_Const(get_mode_null(mode)); + ir_node *const in[2] = { one, zero }; + ir_node *const val = new_d_Phi(dbgi, lengthof(in), in, mode); return val; } @@ -2772,15 +2762,9 @@ normal_node: case EXPR_BINARY_DIV: case EXPR_BINARY_DIV_ASSIGN: { ir_node *pin = new_Pin(new_NoMem()); - ir_node *op; - ir_node *res; - if (mode_is_float(mode)) { - op = new_d_Quot(dbgi, pin, left, right, mode, op_pin_state_floats); - res = new_d_Proj(dbgi, op, mode, pn_Quot_res); - } else { - op = new_d_Div(dbgi, pin, left, right, mode, op_pin_state_floats); - res = new_d_Proj(dbgi, op, mode, pn_Div_res); - } + ir_node *op = new_d_Div(dbgi, pin, left, right, mode, + op_pin_state_floats); + ir_node *res = new_d_Proj(dbgi, op, mode, pn_Div_res); return res; } case EXPR_BINARY_MOD: @@ -2803,7 +2787,7 @@ static ir_node *create_lazy_op(const binary_expression_t *expression) type_t *type = skip_typeref(expression->base.type); ir_mode *mode = get_ir_mode_arithmetic(type); - if (is_constant_expression(expression->left)) { + if (is_constant_expression(expression->left) == EXPR_CLASS_CONSTANT) { bool val = fold_constant_to_bool(expression->left); expression_kind_t ekind = expression->base.kind; assert(ekind == EXPR_BINARY_LOGICAL_AND || ekind == EXPR_BINARY_LOGICAL_OR); @@ -2817,11 +2801,9 @@ static ir_node *create_lazy_op(const binary_expression_t *expression) } } - if (is_constant_expression(expression->right)) { + if (is_constant_expression(expression->right) == EXPR_CLASS_CONSTANT) { bool valr = fold_constant_to_bool(expression->right); - return valr ? - new_Const(get_mode_one(mode)) : - new_Const(get_mode_null(mode)); + return create_Const_from_bool(mode, valr); } return produce_condition_result(expression->right, mode, dbgi); @@ -2873,13 +2855,12 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression) case EXPR_BINARY_ISLESSEQUAL: case EXPR_BINARY_ISLESSGREATER: case EXPR_BINARY_ISUNORDERED: { - dbg_info *dbgi = get_dbg_info(&expression->base.source_position); - ir_node *left = expression_to_firm(expression->left); - ir_node *right = expression_to_firm(expression->right); - ir_node *cmp = new_d_Cmp(dbgi, left, right); - long pnc = get_pnc(kind, expression->left->base.type); - ir_node *proj = new_d_Proj(dbgi, cmp, mode_b, pnc); - return proj; + dbg_info *dbgi = get_dbg_info(&expression->base.source_position); + ir_node *left = expression_to_firm(expression->left); + ir_node *right = expression_to_firm(expression->right); + ir_relation relation = get_relation(kind); + ir_node *cmp = new_d_Cmp(dbgi, left, right, relation); + return cmp; } case EXPR_BINARY_ASSIGN: { ir_node *addr = expression_to_addr(expression->left); @@ -3054,6 +3035,11 @@ static ir_node *sizeof_to_firm(const typeprop_expression_t *expression) && expression->tp_expression != NULL) { expression_to_firm(expression->tp_expression); } + /* strange gnu extensions: sizeof(function) == 1 */ + if (is_type_function(type)) { + ir_mode *mode = get_ir_mode_storage(type_size_t); + return new_Const(get_mode_one(mode)); + } return get_type_size_node(type); } @@ -3093,7 +3079,12 @@ static ir_node *alignof_to_firm(const typeprop_expression_t *expression) if (tp_expression != NULL) { entity_t *entity = get_expression_entity(tp_expression); if (entity != NULL) { - alignment = get_cparser_entity_alignment(entity); + if (entity->kind == ENTITY_FUNCTION) { + /* a gnu-extension */ + alignment = 1; + } else { + alignment = get_cparser_entity_alignment(entity); + } } } @@ -3119,7 +3110,7 @@ static ir_tarval *fold_constant_to_tarval(const expression_t *expression) init_ir_types(); - assert(is_constant_expression(expression)); + assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT); ir_graph *old_current_ir_graph = current_ir_graph; current_ir_graph = get_const_code_irg(); @@ -3162,7 +3153,7 @@ 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)) { + if (is_constant_expression(expression->condition) == EXPR_CLASS_CONSTANT) { bool val = fold_constant_to_bool(expression->condition); if (val) { expression_t *true_expression = expression->true_expression; @@ -3174,51 +3165,47 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression) } } - ir_node *cur_block = get_cur_block(); + ir_node *const true_block = new_immBlock(); + ir_node *const false_block = new_immBlock(); + ir_node *const cond_expr = create_condition_evaluation(expression->condition, true_block, false_block); + mature_immBlock(true_block); + mature_immBlock(false_block); - /* create the true block */ - ir_node *true_block = new_immBlock(); set_cur_block(true_block); + ir_node *true_val; + if (expression->true_expression != NULL) { + true_val = expression_to_firm(expression->true_expression); + } else if (cond_expr != NULL && get_irn_mode(cond_expr) != mode_b) { + true_val = cond_expr; + } else { + /* Condition ended with a short circuit (&&, ||, !) operation or a + * comparison. Generate a "1" as value for the true branch. */ + true_val = new_Const(get_mode_one(mode_Is)); + } + ir_node *const true_jmp = new_d_Jmp(dbgi); - ir_node *true_val = expression->true_expression != NULL ? - expression_to_firm(expression->true_expression) : NULL; - ir_node *true_jmp = new_Jmp(); - - /* create the false block */ - ir_node *false_block = new_immBlock(); set_cur_block(false_block); - - ir_node *false_val = expression_to_firm(expression->false_expression); - ir_node *false_jmp = new_Jmp(); - - /* create the condition evaluation */ - set_cur_block(cur_block); - ir_node *const cond_expr = create_condition_evaluation(expression->condition, true_block, false_block); - if (expression->true_expression == NULL) { - if (cond_expr != NULL && get_irn_mode(cond_expr) != mode_b) { - true_val = cond_expr; - } else { - /* Condition ended with a short circuit (&&, ||, !) operation or a - * comparison. Generate a "1" as value for the true branch. */ - true_val = new_Const(get_mode_one(mode_Is)); - } - } - mature_immBlock(true_block); - mature_immBlock(false_block); + ir_node *const false_val = expression_to_firm(expression->false_expression); + ir_node *const false_jmp = new_d_Jmp(dbgi); /* create the common block */ - ir_node *in_cf[2] = { true_jmp, false_jmp }; - ir_node *block = new_Block(2, in_cf); + ir_node *const in_cf[2] = { true_jmp, false_jmp }; + ir_node *const block = new_Block(lengthof(in_cf), in_cf); set_cur_block(block); /* TODO improve static semantics, so either both or no values are NULL */ if (true_val == NULL || false_val == NULL) return NULL; - ir_node *in[2] = { true_val, false_val }; - ir_mode *mode = get_irn_mode(true_val); - assert(get_irn_mode(false_val) == mode); - ir_node *val = new_d_Phi(dbgi, 2, in, mode); + ir_node *const in[2] = { true_val, false_val }; + type_t *const type = skip_typeref(expression->base.type); + ir_mode *mode; + if (is_type_compound(type)) { + mode = mode_P; + } else { + mode = get_ir_mode_arithmetic(type); + } + ir_node *const val = new_d_Phi(dbgi, lengthof(in), in, mode); return val; } @@ -3500,15 +3487,9 @@ static ir_node *expression_to_addr(const expression_t *expression) static ir_node *builtin_constant_to_firm( const builtin_constant_expression_t *expression) { - ir_mode *mode = get_ir_mode_arithmetic(expression->base.type); - long v; - - if (is_constant_expression(expression->value)) { - v = 1; - } else { - v = 0; - } - return new_Const_long(mode, v); + ir_mode *const mode = get_ir_mode_arithmetic(expression->base.type); + bool const v = is_constant_expression(expression->value) == EXPR_CLASS_CONSTANT; + return create_Const_from_bool(mode, v); } static ir_node *builtin_types_compatible_to_firm( @@ -3516,9 +3497,9 @@ static ir_node *builtin_types_compatible_to_firm( { type_t *const left = get_unqualified_type(skip_typeref(expression->left)); type_t *const right = get_unqualified_type(skip_typeref(expression->right)); - long const value = types_compatible(left, right) ? 1 : 0; + bool const value = types_compatible(left, right); ir_mode *const mode = get_ir_mode_arithmetic(expression->base.type); - return new_Const_long(mode, value); + return create_Const_from_bool(mode, value); } static ir_node *get_label_block(label_t *label) @@ -3687,15 +3668,14 @@ static ir_node *expression_to_firm(const expression_t *expression) return res; } - if (is_constant_expression(expression)) { + if (is_constant_expression(expression) == EXPR_CLASS_CONSTANT) { + bool const constant_folding_old = constant_folding; + constant_folding = true; ir_node *res = _expression_to_firm(expression); + constant_folding = constant_folding_old; ir_mode *mode = get_ir_mode_arithmetic(expression->base.type); assert(is_Const(res)); - if (is_Const_null(res)) { - return new_Const_long(mode, 0); - } else { - return new_Const_long(mode, 1); - } + return create_Const_from_bool(mode, !is_Const_null(res)); } /* we have to produce a 0/1 from the mode_b expression */ @@ -3757,7 +3737,7 @@ static ir_node *create_condition_evaluation(const expression_t *expression, /* 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)) { + if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) { bool cnst = fold_constant_to_bool(argument->expression); cond_jmp_predicate pred; @@ -4289,7 +4269,7 @@ static void create_dynamic_null_initializer(ir_entity *entity, dbg_info *dbgi, } ir_mode *value_mode = get_type_mode(ent_type); - ir_node *node = new_Const_long(value_mode, 0); + ir_node *node = new_Const(get_mode_null(value_mode)); /* is it a bitfield type? */ if (is_Primitive_type(ent_type) && @@ -4421,7 +4401,7 @@ static void create_local_initializer(initializer_t *initializer, dbg_info *dbgi, return; } - if (!is_constant_initializer(initializer)) { + if (is_constant_initializer(initializer) == EXPR_CLASS_VARIABLE) { bool old_initializer_use_bitfield_basetype = initializer_use_bitfield_basetype; initializer_use_bitfield_basetype = true; @@ -4866,135 +4846,126 @@ static void declaration_statement_to_firm(declaration_statement_t *statement) static void if_statement_to_firm(if_statement_t *statement) { - ir_node *cur_block = get_cur_block(); - - ir_node *fallthrough_block = NULL; - - /* the true (blocks) */ - ir_node *const true_block = new_immBlock(); - set_cur_block(true_block); - statement_to_firm(statement->true_statement); + /* Create the condition. */ + ir_node *true_block = NULL; + ir_node *false_block = NULL; if (get_cur_block() != NULL) { - ir_node *jmp = new_Jmp(); - if (fallthrough_block == NULL) - fallthrough_block = new_immBlock(); - add_immBlock_pred(fallthrough_block, jmp); + true_block = new_immBlock(); + false_block = new_immBlock(); + create_condition_evaluation(statement->condition, true_block, false_block); + mature_immBlock(true_block); } - /* the false (blocks) */ - ir_node *false_block = NULL; + /* Create the false statement. + * Handle false before true, so if no false statement is present, then the + * empty false block is reused as fallthrough block. */ + ir_node *fallthrough_block = NULL; if (statement->false_statement != NULL) { - false_block = new_immBlock(); + if (false_block != NULL) { + mature_immBlock(false_block); + } set_cur_block(false_block); - statement_to_firm(statement->false_statement); if (get_cur_block() != NULL) { - ir_node *jmp = new_Jmp(); - if (fallthrough_block == NULL) - fallthrough_block = new_immBlock(); - add_immBlock_pred(fallthrough_block, jmp); + fallthrough_block = new_immBlock(); + add_immBlock_pred(fallthrough_block, new_Jmp()); } + } else { + fallthrough_block = false_block; } - /* create the condition */ - if (cur_block != NULL) { - if (false_block == NULL) { - if (fallthrough_block == NULL) - fallthrough_block = new_immBlock(); - false_block = fallthrough_block; + /* Create the true statement. */ + set_cur_block(true_block); + statement_to_firm(statement->true_statement); + if (get_cur_block() != NULL) { + if (fallthrough_block == NULL) { + fallthrough_block = new_immBlock(); } - - set_cur_block(cur_block); - create_condition_evaluation(statement->condition, true_block, - false_block); + add_immBlock_pred(fallthrough_block, new_Jmp()); } - mature_immBlock(true_block); - if (false_block != fallthrough_block && false_block != NULL) { - mature_immBlock(false_block); - } + /* Handle the block after the if-statement. */ if (fallthrough_block != NULL) { mature_immBlock(fallthrough_block); } - set_cur_block(fallthrough_block); } -static void while_statement_to_firm(while_statement_t *statement) +/* Create a jump node which jumps into target_block, if the current block is + * reachable. */ +static void jump_if_reachable(ir_node *const target_block) { - /* create the header block */ - ir_node *header_block = new_immBlock(); if (get_cur_block() != NULL) { - ir_node *const jmp = new_Jmp(); - add_immBlock_pred(header_block, jmp); - } - - /* the loop body */ - ir_node *old_continue_label = continue_label; - ir_node *old_break_label = break_label; - continue_label = header_block; - break_label = NULL; - - ir_node *body_block = new_immBlock(); - set_cur_block(body_block); - statement_to_firm(statement->body); - ir_node *false_block = break_label; - - assert(continue_label == header_block); - continue_label = old_continue_label; - break_label = old_break_label; - - if (get_cur_block() != NULL) { - ir_node *const jmp = new_Jmp(); - add_immBlock_pred(header_block, jmp); + add_immBlock_pred(target_block, new_Jmp()); } +} - /* shortcut for while(true) */ - if (is_constant_expression(statement->condition) - && fold_constant_to_bool(statement->condition) != 0) { - set_cur_block(header_block); - ir_node *header_jmp = new_Jmp(); - add_immBlock_pred(body_block, header_jmp); +static void while_statement_to_firm(while_statement_t *statement) +{ + /* Create the header block */ + ir_node *const header_block = new_immBlock(); + jump_if_reachable(header_block); + + /* Create the condition. */ + ir_node * body_block; + ir_node * false_block; + expression_t *const cond = statement->condition; + if (is_constant_expression(cond) == EXPR_CLASS_CONSTANT && + fold_constant_to_bool(cond)) { + /* Shortcut for while (true). */ + body_block = header_block; + false_block = NULL; - keep_alive(body_block); - keep_all_memory(body_block); - set_cur_block(body_block); + keep_alive(header_block); + keep_all_memory(header_block); } else { - if (false_block == NULL) { - false_block = new_immBlock(); - } + body_block = new_immBlock(); + false_block = new_immBlock(); - /* create the condition */ set_cur_block(header_block); - - create_condition_evaluation(statement->condition, body_block, - false_block); + create_condition_evaluation(cond, body_block, false_block); + mature_immBlock(body_block); } - mature_immBlock(body_block); + ir_node *const old_continue_label = continue_label; + ir_node *const old_break_label = break_label; + continue_label = header_block; + break_label = false_block; + + /* Create the loop body. */ + set_cur_block(body_block); + statement_to_firm(statement->body); + jump_if_reachable(header_block); + mature_immBlock(header_block); + assert(false_block == NULL || false_block == break_label); + false_block = break_label; if (false_block != NULL) { mature_immBlock(false_block); } - set_cur_block(false_block); + + assert(continue_label == header_block); + continue_label = old_continue_label; + break_label = old_break_label; } -static void do_while_statement_to_firm(do_while_statement_t *statement) +static ir_node *get_break_label(void) { - ir_node *jmp = NULL; - if (get_cur_block() != NULL) { - jmp = new_Jmp(); + if (break_label == NULL) { + break_label = new_immBlock(); } + return break_label; +} +static void do_while_statement_to_firm(do_while_statement_t *statement) +{ /* create the header block */ ir_node *header_block = new_immBlock(); /* the loop body */ ir_node *body_block = new_immBlock(); - if (jmp != NULL) { - add_immBlock_pred(body_block, jmp); - } + jump_if_reachable(body_block); ir_node *old_continue_label = continue_label; ir_node *old_break_label = break_label; @@ -5003,28 +4974,20 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) set_cur_block(body_block); statement_to_firm(statement->body); - ir_node *false_block = break_label; + ir_node *const false_block = get_break_label(); assert(continue_label == header_block); continue_label = old_continue_label; break_label = old_break_label; - if (get_cur_block() != NULL) { - ir_node *body_jmp = new_Jmp(); - add_immBlock_pred(header_block, body_jmp); - mature_immBlock(header_block); - } - - if (false_block == NULL) { - false_block = new_immBlock(); - } + jump_if_reachable(header_block); /* create the condition */ + mature_immBlock(header_block); set_cur_block(header_block); create_condition_evaluation(statement->condition, body_block, false_block); mature_immBlock(body_block); - mature_immBlock(header_block); mature_immBlock(false_block); set_cur_block(false_block); @@ -5032,8 +4995,6 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) static void for_statement_to_firm(for_statement_t *statement) { - ir_node *jmp = NULL; - /* create declarations */ entity_t *entity = statement->scope.entities; for ( ; entity != NULL; entity = entity->base.next) { @@ -5055,69 +5016,67 @@ static void for_statement_to_firm(for_statement_t *statement) if (statement->initialisation != NULL) { expression_to_firm(statement->initialisation); } - - jmp = new_Jmp(); } + /* Create the header block */ + ir_node *const header_block = new_immBlock(); + jump_if_reachable(header_block); - /* create the step block */ - ir_node *const step_block = new_immBlock(); - set_cur_block(step_block); - if (statement->step != NULL) { - expression_to_firm(statement->step); - } - ir_node *const step_jmp = new_Jmp(); + /* Create the condition. */ + ir_node *body_block; + ir_node *false_block; + if (statement->condition != NULL) { + body_block = new_immBlock(); + false_block = new_immBlock(); - /* create the header block */ - ir_node *const header_block = new_immBlock(); - set_cur_block(header_block); - if (jmp != NULL) { - add_immBlock_pred(header_block, jmp); + set_cur_block(header_block); + create_condition_evaluation(statement->condition, body_block, false_block); + mature_immBlock(body_block); + } else { + /* for-ever. */ + body_block = header_block; + false_block = NULL; + + keep_alive(header_block); + keep_all_memory(header_block); } - add_immBlock_pred(header_block, step_jmp); - /* the false block */ - ir_node *const false_block = new_immBlock(); + /* Create the step block, if necessary. */ + ir_node * step_block = header_block; + expression_t *const step = statement->step; + if (step != NULL) { + step_block = new_immBlock(); + } - /* the loop body */ ir_node *const old_continue_label = continue_label; ir_node *const old_break_label = break_label; continue_label = step_block; break_label = false_block; - ir_node *const body_block = new_immBlock(); + /* Create the loop body. */ set_cur_block(body_block); statement_to_firm(statement->body); + jump_if_reachable(step_block); - assert(continue_label == step_block); - assert(break_label == false_block); - continue_label = old_continue_label; - break_label = old_break_label; - - if (get_cur_block() != NULL) { - jmp = new_Jmp(); - add_immBlock_pred(step_block, jmp); - } - - /* create the condition */ - set_cur_block(header_block); - if (statement->condition != NULL) { - create_condition_evaluation(statement->condition, body_block, - false_block); - } else { - keep_alive(header_block); - keep_all_memory(header_block); - jmp = new_Jmp(); - add_immBlock_pred(body_block, jmp); + /* Create the step code. */ + if (step != NULL) { + mature_immBlock(step_block); + set_cur_block(step_block); + expression_to_firm(step); + jump_if_reachable(header_block); } - mature_immBlock(body_block); - mature_immBlock(false_block); - mature_immBlock(step_block); mature_immBlock(header_block); - mature_immBlock(false_block); - + assert(false_block == NULL || false_block == break_label); + false_block = break_label; + if (false_block != NULL) { + mature_immBlock(false_block); + } set_cur_block(false_block); + + assert(continue_label == step_block); + continue_label = old_continue_label; + break_label = old_break_label; } static void create_jump_statement(const statement_t *statement, @@ -5133,14 +5092,6 @@ static void create_jump_statement(const statement_t *statement, set_cur_block(NULL); } -static ir_node *get_break_label(void) -{ - if (break_label == NULL) { - break_label = new_immBlock(); - } - return break_label; -} - static void switch_statement_to_firm(switch_statement_t *statement) { ir_node *first_block = NULL; @@ -5223,10 +5174,7 @@ static void switch_statement_to_firm(switch_statement_t *statement) statement_to_firm(statement->body); - if (get_cur_block() != NULL) { - ir_node *jmp = new_Jmp(); - add_immBlock_pred(get_break_label(), jmp); - } + jump_if_reachable(get_break_label()); if (!saw_default_label && first_block != NULL) { set_cur_block(first_block); @@ -5251,60 +5199,46 @@ static void case_label_to_firm(const case_label_statement_t *statement) if (statement->is_empty_range) return; - dbg_info *dbgi = get_dbg_info(&statement->base.source_position); - - ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp()); - - ir_node *proj; ir_node *block = new_immBlock(); + /* Fallthrough from previous case */ + jump_if_reachable(block); if (current_switch_cond != NULL) { set_cur_block(get_nodes_block(current_switch_cond)); + dbg_info *const dbgi = get_dbg_info(&statement->base.source_position); if (statement->expression != NULL) { long pn = statement->first_case; long end_pn = statement->last_case; assert(pn <= end_pn); /* create jumps for all cases in the given range */ do { - proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn); + ir_node *const proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn); add_immBlock_pred(block, proj); } while (pn++ < end_pn); } else { saw_default_label = true; - proj = new_d_Proj(dbgi, current_switch_cond, mode_X, - current_switch->default_proj_nr); - + ir_node *const proj = new_d_Proj(dbgi, current_switch_cond, mode_X, + current_switch->default_proj_nr); add_immBlock_pred(block, proj); } } - if (fallthrough != NULL) { - add_immBlock_pred(block, fallthrough); - } mature_immBlock(block); set_cur_block(block); - if (statement->statement != NULL) { - statement_to_firm(statement->statement); - } + statement_to_firm(statement->statement); } static void label_to_firm(const label_statement_t *statement) { ir_node *block = get_label_block(statement->label); - - if (get_cur_block() != NULL) { - ir_node *jmp = new_Jmp(); - add_immBlock_pred(block, jmp); - } + jump_if_reachable(block); set_cur_block(block); keep_alive(block); keep_all_memory(block); - if (statement->statement != NULL) { - statement_to_firm(statement->statement); - } + statement_to_firm(statement->statement); } static void goto_to_firm(const goto_statement_t *statement) @@ -5570,13 +5504,13 @@ static void asm_statement_to_firm(const asm_statement_t *statement) } } -static void ms_try_statement_to_firm(ms_try_statement_t *statement) +static void ms_try_statement_to_firm(ms_try_statement_t *statement) { statement_to_firm(statement->try_statement); warningf(&statement->base.source_position, "structured exception handling ignored"); } -static void leave_statement_to_firm(leave_statement_t *statement) +static void leave_statement_to_firm(leave_statement_t *statement) { errorf(&statement->base.source_position, "__leave not supported yet"); }