main: rework preprocessor invocation
[cparser] / ast2firm.c
index 31aa71d..b425a1e 100644 (file)
@@ -1468,16 +1468,13 @@ static ir_node *get_local_frame(ir_entity *const ent)
 }
 
 /**
- * Keep all memory edges of the given block.
+ * Keep the current block and memory.
+ * This is necessary for all loops, because they could become infinite.
  */
-static void keep_all_memory(ir_node *block)
+static void keep_loop(void)
 {
-       ir_node *old = get_cur_block();
-
-       set_cur_block(block);
+       keep_alive(get_cur_block());
        keep_alive(get_store());
-       /* TODO: keep all memory edges from restricted pointers */
-       set_cur_block(old);
 }
 
 static ir_node *enum_constant_to_firm(reference_expression_t const *const ref)
@@ -2915,8 +2912,6 @@ bool fold_constant_to_bool(const expression_t *expression)
 
 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) == EXPR_CLASS_CONSTANT) {
                bool val = fold_constant_to_bool(expression->condition);
@@ -2957,7 +2952,8 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression)
                ir_node *const false_val = expression_to_firm(expression->false_expression);
                jump_to_target(&exit_target);
                if (val) {
-                       ir_node *const in[] = { val, false_val };
+                       ir_node  *const in[] = { val, false_val };
+                       dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
                        val = new_rd_Phi(dbgi, exit_target.block, lengthof(in), in, get_irn_mode(val));
                } else {
                        val = false_val;
@@ -3428,26 +3424,33 @@ static ir_node *create_condition_evaluation(expression_t const *const expression
                break;
        }
 
-       dbg_info *dbgi       = get_dbg_info(&expression->base.source_position);
-       ir_node  *cond_expr  = _expression_to_firm(expression);
-       ir_node  *condition  = create_conv(dbgi, cond_expr, mode_b);
-       ir_node  *cond       = new_d_Cond(dbgi, condition);
-       ir_node  *true_proj  = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
-       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) && is_Cond(cond)) {
-               call_argument_t *argument = expression->call.arguments->next;
-               if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
-                       bool               const cnst = fold_constant_to_bool(argument->expression);
-                       cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
-                       set_Cond_jmp_pred(cond, pred);
+       ir_node *cond_expr = _expression_to_firm(expression);
+       if (is_Const(cond_expr)) {
+               if (tarval_is_null(get_Const_tarval(cond_expr))) {
+                       jump_to_target(false_target);
+               } else {
+                       jump_to_target(true_target);
+               }
+       } else {
+               dbg_info *dbgi       = get_dbg_info(&expression->base.source_position);
+               ir_node  *condition  = create_conv(dbgi, cond_expr, mode_b);
+               ir_node  *cond       = new_d_Cond(dbgi, condition);
+               ir_node  *true_proj  = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
+               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) && is_Cond(cond)) {
+                       call_argument_t *argument = expression->call.arguments->next;
+                       if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
+                               bool               const cnst = fold_constant_to_bool(argument->expression);
+                               cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
+                               set_Cond_jmp_pred(cond, pred);
+                       }
                }
-       }
-
-       add_pred_to_jump_target(true_target,  true_proj);
-       add_pred_to_jump_target(false_target, false_proj);
 
+               add_pred_to_jump_target(true_target,  true_proj);
+               add_pred_to_jump_target(false_target, false_proj);
+       }
        set_unreachable_now();
        return cond_expr;
 }
@@ -4520,6 +4523,7 @@ static ir_node *do_while_statement_to_firm(do_while_statement_t *statement)
                init_jump_target(&body_target, NULL);
                jump_to_target(&body_target);
                enter_immature_jump_target(&body_target);
+               keep_loop();
                statement_to_firm(statement->body);
                jump_to_target(&continue_target);
                if (enter_jump_target(&continue_target))
@@ -4556,6 +4560,7 @@ static ir_node *for_statement_to_firm(for_statement_t *statement)
        init_jump_target(&header_target, NULL);
        jump_to_target(&header_target);
        enter_immature_jump_target(&header_target);
+       keep_loop();
 
        expression_t *const step = statement->step;
        PUSH_BREAK(NULL);
@@ -4568,10 +4573,6 @@ static ir_node *for_statement_to_firm(for_statement_t *statement)
                init_jump_target(&body_target, NULL);
                create_condition_evaluation(cond, &body_target, &break_target);
                enter_jump_target(&body_target);
-       } else {
-               /* for-ever. */
-               keep_alive(header_target.block);
-               keep_all_memory(header_target.block);
        }
 
        /* Create the loop body. */
@@ -4692,8 +4693,7 @@ static ir_node *label_to_firm(const label_statement_t *statement)
                enter_jump_target(&label->target);
        } else {
                enter_immature_jump_target(&label->target);
-               keep_alive(label->target.block);
-               keep_all_memory(label->target.block);
+               keep_loop();
        }
 
        return statement_to_firm(statement->statement);