forbid calls of new_XXX and new_d_XXX when not in phase_building (only new_r_XXX...
[libfirm] / ir / opt / loop.c
index fbc964e..a6cf45f 100644 (file)
@@ -159,13 +159,13 @@ static void do_print_stats(void)
 
 /* Commandline parameters */
 typedef struct loop_opt_params_t {
-       unsigned max_loop_size;         /* Maximum number of nodes */
-       int      depth_adaption;        /* Loop nest depth adaption */
-       unsigned allowed_calls;         /* Number of calls allowed */
-       unsigned count_phi:1;           /* Count phi nodes */
-       unsigned count_proj:1;          /* Count projections */
+       unsigned max_loop_size;     /* Maximum number of nodes */
+       int      depth_adaption;    /* Loop nest depth adaption */
+       unsigned allowed_calls;     /* Number of calls allowed */
+       unsigned count_phi:1;       /* Count phi nodes */
+       unsigned count_proj:1;      /* Count projections */
 
-       unsigned max_cc_size;           /* Maximum condition chain size */
+       unsigned max_cc_size;       /* Maximum condition chain size */
 
        unsigned allow_const_unrolling:1;
        unsigned allow_invar_unrolling:1;
@@ -176,22 +176,22 @@ static loop_opt_params_t opt_params;
 
 /* Loop analysis informations */
 typedef struct loop_info_t {
-       unsigned nodes;                 /* node count */
-       unsigned ld_st;                 /* load and store nodes */
-       unsigned calls;                 /* number of calls */
-       unsigned cf_outs;               /* number of cf edges which leave the loop */
-       entry_edge cf_out;              /* single loop leaving cf edge */
-       int be_src_pos;                 /* position of the single own backedge in the head */
+       unsigned nodes;         /* node count */
+       unsigned ld_st;         /* load and store nodes */
+       unsigned calls;         /* number of calls */
+       unsigned cf_outs;       /* number of cf edges which leave the loop */
+       entry_edge cf_out;      /* single loop leaving cf edge */
+       int be_src_pos;         /* position of the single own backedge in the head */
 
        /* for inversion */
-       unsigned cc_size;               /* nodes in the condition chain */
+       unsigned cc_size;       /* nodes in the condition chain */
 
        /* for unrolling */
-       unsigned max_unroll;            /* Number of unrolls satisfying max_loop_size */
-       unsigned exit_cond;                     /* 1 if condition==true exits the loop.  */
-       unsigned latest_value:1;        /* 1 if condition is checked against latest counter value */
-       unsigned needs_backedge:1;      /* 0 if loop is completely unrolled */
-       unsigned decreasing:1;          /* Step operation is_Sub, or step is<0 */
+       unsigned max_unroll;        /* Number of unrolls satisfying max_loop_size */
+       unsigned exit_cond;         /* 1 if condition==true exits the loop.  */
+       unsigned latest_value:1;    /* 1 if condition is checked against latest counter value */
+       unsigned needs_backedge:1;  /* 0 if loop is completely unrolled */
+       unsigned decreasing:1;      /* Step operation is_Sub, or step is<0 */
 
        /* IV informations of a simple loop */
        ir_node *start_val;
@@ -200,10 +200,10 @@ typedef struct loop_info_t {
        ir_node *iteration_phi;
        ir_node *add;
 
-       tarval *count_tar;                                      /* Number of loop iterations */
+       tarval *count_tar;                  /* Number of loop iterations */
 
-       ir_node *duff_cond;                                     /* Duff mod */
-       unrolling_kind_flag unroll_kind;        /* constant or invariant unrolling */
+       ir_node *duff_cond;                 /* Duff mod */
+       unrolling_kind_flag unroll_kind;    /* constant or invariant unrolling */
 } loop_info_t;
 
 /* Information about the current loop */
@@ -370,8 +370,9 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, int fi
        /* Prevents creation of phi that would be bad anyway.
         * Dead and bad blocks. */
        if (get_irn_arity(block) < 1 || is_Bad(block)) {
+               ir_graph *irg = get_irn_irg(block);
                DB((dbg, LEVEL_5, "ssa bad %N\n", block));
-               return new_Bad();
+               return new_r_Bad(irg);
        }
 
        if (block == ssa_second_def_block && !first) {
@@ -407,7 +408,7 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, int fi
        /* create a new Phi */
        NEW_ARR_A(ir_node*, in, n_cfgpreds);
        for (i = 0; i < n_cfgpreds; ++i)
-               in[i] = new_Unknown(mode);
+               in[i] = new_r_Unknown(irg, mode);
 
        phi = new_r_Phi(block, n_cfgpreds, in, mode);
        /* Important: always keep block phi list up to date. */
@@ -650,8 +651,6 @@ static ir_node *copy_node(ir_node *node)
        }
 
        if (is_Block(cp)) {
-               /* We may not keep the old macroblock. */
-               set_Block_MacroBlock(cp, cp);
                set_Block_mark(cp, 0);
        }
 
@@ -666,7 +665,7 @@ static ir_node *copy_node(ir_node *node)
  * Order of ins is important for later usage.
  */
 static void copy_walk(ir_node *node, walker_condition *walk_condition,
-               ir_loop *set_loop)
+                      ir_loop *set_loop)
 {
        int i;
        int arity;
@@ -982,7 +981,7 @@ static unsigned find_condition_chain(ir_node *block)
         *   / A*  B           /    |
         *  / /\   /          ?     |
         *   /   C*      =>      D  |
-        *          /  D               Head |
+        *      /  D           Head |
         *     /               A  \_|
         *                      C
         */
@@ -1020,10 +1019,11 @@ static void fix_copy_inversion(void)
        ir_node **ins;
        ir_node **phis;
        ir_node *phi, *next;
-       ir_node *head_cp        = get_inversion_copy(loop_head);
-       int arity                       = get_irn_arity(head_cp);
-       int backedges           = get_backedge_n(head_cp, 0);
-       int new_arity           = arity - backedges;
+       ir_node *head_cp    = get_inversion_copy(loop_head);
+       ir_graph *irg       = get_irn_irg(head_cp);
+       int arity           = get_irn_arity(head_cp);
+       int backedges       = get_backedge_n(head_cp, 0);
+       int new_arity       = arity - backedges;
        int pos;
        int i;
 
@@ -1036,7 +1036,7 @@ static void fix_copy_inversion(void)
                        ins[pos++] = get_irn_n(head_cp, i);
        }
 
-       new_head = new_Block(new_arity, ins);
+       new_head = new_r_Block(irg, new_arity, ins);
 
        phis = NEW_ARR_F(ir_node *, 0);
 
@@ -1074,9 +1074,10 @@ static void fix_head_inversion(void)
        ir_node **ins;
        ir_node *phi, *next;
        ir_node **phis;
-       int arity                       = get_irn_arity(loop_head);
-       int backedges           = get_backedge_n(loop_head, 0);
-       int new_arity           = backedges;
+       ir_graph *irg       = get_irn_irg(loop_head);
+       int arity           = get_irn_arity(loop_head);
+       int backedges       = get_backedge_n(loop_head, 0);
+       int new_arity       = backedges;
        int pos;
        int i;
 
@@ -1089,7 +1090,7 @@ static void fix_head_inversion(void)
                        ins[pos++] = get_irn_n(loop_head, i);
        }
 
-       new_head = new_Block(new_arity, ins);
+       new_head = new_r_Block(irg, new_arity, ins);
 
        phis = NEW_ARR_F(ir_node *, 0);
 
@@ -1331,7 +1332,7 @@ static void unrolling_fix_loop_head_inv(void)
 {
        ir_node *ins[2];
        ir_node *phi;
-       ir_node *proj = new_Proj(loop_info.duff_cond, mode_X, 0);
+       ir_node *proj = new_r_Proj(loop_info.duff_cond, mode_X, 0);
        ir_node *head_pred = get_irn_n(loop_head, loop_info.be_src_pos);
        ir_node *loop_condition = get_unroll_copy(head_pred, unroll_nr - 1);
 
@@ -1421,7 +1422,7 @@ static void place_copies(int copies)
                         * and one from the previous unrolled loop. */
                        ir_node *ins[2];
                        /* Calculate corresponding projection of mod result for this copy c */
-                       ir_node *proj = new_Proj(loop_info.duff_cond, mode_X, unroll_nr - c - 1);
+                       ir_node *proj = new_r_Proj(loop_info.duff_cond, mode_X, unroll_nr - c - 1);
 
                        ins[0] = new_jmp;
                        ins[1] = proj;
@@ -1524,14 +1525,15 @@ static ir_node *clone_phis_sans_bes(ir_node *node, ir_node *be_block)
                if (! is_own_backedge(be_block, i)) {
                        ins[c] = get_irn_n(node, i);
                        ++c;
-               }
-       /*      } else {
+#if 0
+               } else {
                        ir_node *pred = get_inr_n(node, i);
                        if (! is_in_loop(pred)) {
                                ins[c] = pred;
                                ++c;
                        }
-               }*/
+#endif
+               }
        }
 
        return new_r_Phi(get_nodes_block(node), c, ins, get_irn_mode(node));
@@ -1542,6 +1544,7 @@ static ir_node *clone_phis_sans_bes(ir_node *node, ir_node *be_block)
 static ir_node *clone_block_sans_bes(ir_node *node, ir_node *be_block)
 {
        ir_node **ins;
+       ir_graph *irg = get_irn_irg(node);
        int arity = get_irn_arity(node);
        int i, c = 0;
 
@@ -1556,7 +1559,7 @@ static ir_node *clone_block_sans_bes(ir_node *node, ir_node *be_block)
                }
        }
 
-       return new_Block(c, ins);
+       return new_r_Block(irg, c, ins);
 }
 
 /* Creates blocks for duffs device, using previously obtained
@@ -1566,6 +1569,7 @@ static void create_duffs_block(void)
 {
        ir_mode *mode;
 
+       ir_graph *irg = get_irn_irg(loop_head);
        ir_node *block1, *count_block, *duff_block;
        ir_node *ems, *ems_divmod, *ems_mod_proj, *cmp_null,
                *cmp_proj, *ems_mode_cond, *x_true, *x_false, *const_null;
@@ -1578,7 +1582,7 @@ static void create_duffs_block(void)
        ir_node *cmp_bad_count, *good_count, *bad_count, *count_phi, *bad_count_neg;
 
        mode = get_irn_mode(loop_info.end_val);
-       const_null = new_Const(get_mode_null(mode));
+       const_null = new_r_Const(irg, get_mode_null(mode));
 
        /* TODO naming
         * 1. Calculate first approach to count.
@@ -1599,7 +1603,7 @@ static void create_duffs_block(void)
                get_irn_mode(loop_info.end_val));
 
        ems_divmod = new_r_DivMod(block1,
-               new_NoMem(),
+               new_r_NoMem(irg),
                ems,
                loop_info.step,
                mode,
@@ -1608,12 +1612,12 @@ static void create_duffs_block(void)
        ems_mod_proj = new_r_Proj(ems_divmod, mode, pn_DivMod_res_mod);
        cmp_null = new_r_Cmp(block1, ems_mod_proj, const_null);
        cmp_proj = new_r_Proj(cmp_null, mode, pn_Cmp_Eq);
-       ems_mode_cond = new_Cond(cmp_proj);
+       ems_mode_cond = new_r_Cond(block1, cmp_proj);
 
        /* ems % step == 0 */
-       x_true = new_Proj(ems_mode_cond, mode_X, pn_Cond_true);
+       x_true = new_r_Proj(ems_mode_cond, mode_X, pn_Cond_true);
        /* ems % step != 0 */
-       x_false = new_Proj(ems_mode_cond, mode_X, pn_Cond_false);
+       x_false = new_r_Proj(ems_mode_cond, mode_X, pn_Cond_false);
 
 
        /* 2. Second block.
@@ -1625,21 +1629,21 @@ static void create_duffs_block(void)
        ins[0] = x_true;
        ins[1] = x_false;
 
-       count_block = new_Block(2, ins);
+       count_block = new_r_Block(irg, 2, ins);
 
        /* Increase loop-taken-count depending on the loop condition
         * uses the latest iv to compare to. */
        if (loop_info.latest_value == 1) {
                /* ems % step == 0 :  +0 */
-               true_val = new_Const(get_mode_null(mode));
+               true_val = new_r_Const(irg, get_mode_null(mode));
                /* ems % step != 0 :  +1 */
-               false_val = new_Const(get_mode_one(mode));
+               false_val = new_r_Const(irg, get_mode_one(mode));
        } else {
                tarval *tv_two = new_tarval_from_long(2, mode);
                /* ems % step == 0 :  +1 */
-               true_val = new_Const(get_mode_one(mode));
+               true_val = new_r_Const(irg, get_mode_one(mode));
                /* ems % step != 0 :  +2 */
-               false_val = new_Const(tv_two);
+               false_val = new_r_Const(irg, tv_two);
        }
 
        ins[0] = true_val;
@@ -1650,7 +1654,7 @@ static void create_duffs_block(void)
        count = new_r_Proj(ems_divmod, mode, pn_DivMod_res_div);
 
        /* (end - start) / step  +  correction */
-       count = new_Add(count, correction, mode);
+       count = new_r_Add(count_block, count, correction, mode);
 
        cmp_bad_count = new_r_Cmp(count_block, count, const_null);
 
@@ -1667,35 +1671,41 @@ static void create_duffs_block(void)
                bad_count_neg = new_r_Proj(cmp_bad_count, mode_X, pn_Cmp_Gt);
        }
 
-       bad_count_neg = new_Cond(bad_count_neg);
-       good_count = new_Proj(bad_count_neg, mode_X, pn_Cond_true);
-       bad_count = new_Proj(ems_mode_cond, mode_X, pn_Cond_false);
+       bad_count_neg = new_r_Cond(count_block, bad_count_neg);
+       good_count = new_r_Proj(bad_count_neg, mode_X, pn_Cond_true);
+       bad_count = new_r_Proj(ems_mode_cond, mode_X, pn_Cond_false);
 
        /* 3. Duff Block
         *    Contains module to decide which loop to start from. */
 
        ins[0] = good_count;
        ins[1] = bad_count;
-       duff_block = new_Block(2, ins);
+       duff_block = new_r_Block(irg, 2, ins);
 
+       /* Matze: I commented this line out because I was in the process of
+        * removing the Abs node. I don't understand that line at all anyway
+        * since no other code here checks for the presence of an Abs or creates
+        * one. So how can we know here that "count" is an Abs node... */
+#if 0
        /* count wants to be positive */
        ins[0] = get_Abs_op(count);
+#endif
        /* Manually feed the aforementioned count = 1 (bad case)*/
-       ins[1] = new_Const(get_mode_one(mode));
+       ins[1] = new_r_Const(irg, get_mode_one(mode));
        count_phi = new_r_Phi(duff_block, 2, ins, mode);
 
-       unroll_c = new_Const(new_tarval_from_long((long)unroll_nr, mode));
+       unroll_c = new_r_Const(irg, new_tarval_from_long((long)unroll_nr, mode));
 
        /* count % unroll_nr */
        duff_mod = new_r_Mod(duff_block,
-               new_NoMem(),
+               new_r_NoMem(irg),
                count_phi,
                unroll_c,
                mode,
                op_pin_state_pinned);
 
-       proj = new_Proj(duff_mod, mode_X, pn_Mod_res);
-       cond = new_Cond(proj);
+       proj = new_r_Proj(duff_mod, mode_X, pn_Mod_res);
+       cond = new_r_Cond(duff_block, proj);
 
        loop_info.duff_cond = cond;
 }
@@ -2029,10 +2039,10 @@ static unsigned are_mode_I(ir_node *n1, ir_node* n2, ir_node *n3)
 static unsigned get_unroll_decision_invariant(void)
 {
 
-       ir_node         *projres, *loop_condition, *iteration_path;
-       unsigned        success, is_latest_val;
-       tarval          *start_tar, *step_tar;
-       ir_mode         *mode;
+       ir_node  *projres, *loop_condition, *iteration_path;
+       unsigned  success, is_latest_val;
+       tarval   *start_tar, *step_tar;
+       ir_mode  *mode;
 
        /* RETURN if loop is not 'simple' */
        projres = is_simple_loop();
@@ -2227,11 +2237,11 @@ static unsigned get_preferred_factor_constant(tarval *count_tar)
 /* TODO split. */
 static unsigned get_unroll_decision_constant(void)
 {
-       ir_node         *projres, *loop_condition, *iteration_path;
-       unsigned        success, is_latest_val;
-       tarval          *start_tar, *end_tar, *step_tar, *diff_tar, *count_tar, *stepped;
-       pn_Cmp          proj_proj, norm_proj;
-       ir_mode         *mode;
+       ir_node  *projres, *loop_condition, *iteration_path;
+       unsigned  success, is_latest_val;
+       tarval   *start_tar, *end_tar, *step_tar, *diff_tar, *count_tar, *stepped;
+       pn_Cmp    proj_proj, norm_proj;
+       ir_mode  *mode;
 
        /* RETURN if loop is not 'simple' */
        projres = is_simple_loop();