Let is_constant_expression() and friends return an enum so constant expressions can...
[cparser] / ast2firm.c
index 3f092b2..1517253 100644 (file)
@@ -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);