Overhaul for_statement_to_firm() so it is more friendly towards SSA construction...
[cparser] / ast2firm.c
index 4db569f..950ee35 100644 (file)
@@ -4913,62 +4913,55 @@ static void if_statement_to_firm(if_statement_t *statement)
 
 static void while_statement_to_firm(while_statement_t *statement)
 {
-       /* 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;
-
+       /* Create the header block */
+       ir_node *const header_block = new_immBlock();
        if (get_cur_block() != NULL) {
-               ir_node *const jmp = new_Jmp();
-               add_immBlock_pred(header_block, jmp);
+               add_immBlock_pred(header_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);
+       /* 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)) {
+               /* 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(cond, body_block, false_block);
+               mature_immBlock(body_block);
+       }
 
-               create_condition_evaluation(statement->condition, body_block,
-                                           false_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);
+       if (get_cur_block() != NULL) {
+               add_immBlock_pred(header_block, new_Jmp());
        }
 
-       mature_immBlock(body_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)
@@ -4998,7 +4991,6 @@ static void do_while_statement_to_firm(do_while_statement_t *statement)
        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) {
@@ -5006,11 +4998,11 @@ static void do_while_statement_to_firm(do_while_statement_t *statement)
        }
 
        /* 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);
@@ -5027,7 +5019,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) {
@@ -5040,67 +5031,73 @@ 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();
+       if (get_cur_block() != NULL) {
+               add_immBlock_pred(header_block, 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 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();
+               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;
 
-       /* 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);
+               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);
-
-       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 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());
+       /* Create the step code. */
+       if (step != NULL) {
+               mature_immBlock(step_block);
+               set_cur_block(step_block);
+               expression_to_firm(step);
+               if (get_cur_block() != NULL) {
+                       add_immBlock_pred(header_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,