X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=1517253b14550a44a59f38a165913ecf60592b27;hb=26aba71a371f0bbcc8afd213b4398d4e4e52a6f2;hp=3f092b22bf6a9410514c44ad78bf1c97d49ea52b;hpb=bb3fa754fef99c9f8f659cff4dc91ec096399266;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 3f092b2..1517253 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -2479,10 +2479,10 @@ static ir_node *handle_assume_compare(dbg_info *dbi, } 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)) { + } else if (is_constant_expression(op1) == EXPR_CLASS_CONSTANT && is_local_variable(op2)) { cmp_val = get_inversed_pnc(cmp_val); var = op2->reference.entity; con = op1; @@ -2639,29 +2639,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; } @@ -2803,7 +2796,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,7 +2810,7 @@ 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)) : @@ -3119,7 +3112,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 +3155,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 +3167,42 @@ 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); + ir_node *const in[2] = { true_val, false_val }; + ir_mode *const 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 val = new_d_Phi(dbgi, lengthof(in), in, mode); return val; } @@ -3503,7 +3487,7 @@ static ir_node *builtin_constant_to_firm( ir_mode *mode = get_ir_mode_arithmetic(expression->base.type); long v; - if (is_constant_expression(expression->value)) { + if (is_constant_expression(expression->value) == EXPR_CLASS_CONSTANT) { v = 1; } else { v = 0; @@ -3687,7 +3671,7 @@ 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) { ir_node *res = _expression_to_firm(expression); ir_mode *mode = get_ir_mode_arithmetic(expression->base.type); assert(is_Const(res)); @@ -3757,7 +3741,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; @@ -4421,7 +4405,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; @@ -4911,19 +4895,27 @@ static void if_statement_to_firm(if_statement_t *statement) set_cur_block(fallthrough_block); } +/* 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) +{ + if (get_cur_block() != NULL) { + add_immBlock_pred(target_block, new_Jmp()); + } +} + static void while_statement_to_firm(while_statement_t *statement) { /* Create the header block */ ir_node *const header_block = new_immBlock(); - if (get_cur_block() != NULL) { - add_immBlock_pred(header_block, new_Jmp()); - } + 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) && fold_constant_to_bool(cond)) { + if (is_constant_expression(cond) == EXPR_CLASS_CONSTANT && + fold_constant_to_bool(cond)) { /* Shortcut for while (true). */ body_block = header_block; false_block = NULL; @@ -4947,9 +4939,7 @@ static void while_statement_to_firm(while_statement_t *statement) /* Create the loop body. */ set_cur_block(body_block); statement_to_firm(statement->body); - if (get_cur_block() != NULL) { - add_immBlock_pred(header_block, new_Jmp()); - } + jump_if_reachable(header_block); mature_immBlock(header_block); assert(false_block == NULL || false_block == break_label); @@ -4964,6 +4954,14 @@ static void while_statement_to_firm(while_statement_t *statement) break_label = old_break_label; } +static ir_node *get_break_label(void) +{ + 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 */ @@ -4971,9 +4969,7 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) /* the loop body */ ir_node *body_block = new_immBlock(); - if (get_cur_block() != NULL) { - add_immBlock_pred(body_block, new_Jmp()); - } + jump_if_reachable(body_block); ir_node *old_continue_label = continue_label; ir_node *old_break_label = break_label; @@ -4982,20 +4978,13 @@ 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); - } - - if (false_block == NULL) { - false_block = new_immBlock(); - } + jump_if_reachable(header_block); /* create the condition */ mature_immBlock(header_block); @@ -5019,7 +5008,6 @@ static void for_statement_to_firm(for_statement_t *statement) create_local_declaration(entity); } - ir_node *jmp = NULL; if (get_cur_block() != NULL) { entity = statement->scope.entities; for ( ; entity != NULL; entity = entity->base.next) { @@ -5032,67 +5020,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) { - add_immBlock_pred(step_block, new_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); } - /* 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); - add_immBlock_pred(body_block, new_Jmp()); - } - - 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, @@ -5108,14 +5096,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; @@ -5198,10 +5178,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); @@ -5227,11 +5204,8 @@ static void case_label_to_firm(const case_label_statement_t *statement) return; ir_node *block = new_immBlock(); - - if (get_cur_block() != NULL) { - /* Fallthrough from previous case */ - add_immBlock_pred(block, new_Jmp()); - } + /* Fallthrough from previous case */ + jump_if_reachable(block); if (current_switch_cond != NULL) { set_cur_block(get_nodes_block(current_switch_cond)); @@ -5262,11 +5236,7 @@ static void case_label_to_firm(const case_label_statement_t *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);