- fixed off-by-one error after phase refactoring
[libfirm] / ir / opt / loop.c
index b0b907b..39df5e5 100644 (file)
@@ -26,6 +26,8 @@
  */
 #include "config.h"
 
+#include "iroptimize.h"
+#include "opt_init.h"
 #include "irnode.h"
 #include "debug.h"
 
 #include "irouts.h"
 #include "iredges.h"
 #include "irtools.h"
-#include "array_t.h"   /* automatic array */
-#include "beutil.h"            /* get_block */
-#include "irloop_t.h"  /* set_irn_loop*/
+#include "array_t.h"
+#include "beutil.h"
+#include "irloop_t.h"
 #include "irpass.h"
 
-#if 0
-       #include "irdump_t.h"
-#endif
-
-
 DEBUG_ONLY(static firm_dbg_module_t *dbg);
 
 /**
@@ -258,7 +255,7 @@ static unsigned is_nodesblock_marked(ir_node* node)
 }
 
 /* Returns the number of blocks in a loop. */
-int get_loop_n_blocks(ir_loop *loop)
+static int get_loop_n_blocks(ir_loop *loop)
 {
        int elements, e;
        int blocks = 0;
@@ -286,7 +283,7 @@ static int duplicate_preds(ir_node* block, unsigned pos, ir_node* newpred)
 
        assert(is_Block(block) && "duplicate_preds may be called for blocks only");
 
-       DB((dbg, LEVEL_1, "duplicate_preds(node %N, pos %d, newpred %N)\n", block, pos, newpred));
+       DB((dbg, LEVEL_5, "duplicate_preds(node %N, pos %d, newpred %N)\n", block, pos, newpred));
 
        block_arity = get_irn_arity(block);
 
@@ -299,26 +296,15 @@ static int duplicate_preds(ir_node* block, unsigned pos, ir_node* newpred)
 
        set_irn_in(block, block_arity + 1, ins);
 
-#if 0
-       block_arity = get_irn_arity(block);
-
-       NEW_ARR_A(ir_node*, ins, block_arity - 1);
-
-       for (i = 0; i < block_arity - 1; ++i) {
-               ins[i] = get_irn_n(block, i);
-       }
-
-       set_irn_in(block, block_arity - 1, ins);
-#endif
-
-#if 0
+       /* LDBG 1 */
+#if 1
        for_each_phi(block, phi) {
                int phi_arity = get_irn_arity(phi);
-               DB((dbg, LEVEL_5, "duplicate_preds: fixing phi %N\n", phi)));
+               DB((dbg, LEVEL_5, "duplicate_preds: fixing phi %N\n", phi));
 
                NEW_ARR_A(ir_node *, ins, block_arity + 1);
                for (i = 0; i < phi_arity; ++i) {
-                       DB((dbg, LEVEL_5, "in %N\n", get_irn_n(phi, i))));
+                       DB((dbg, LEVEL_5, "pos %N\n", get_irn_n(phi, i)));
                        ins[i] = get_irn_n(phi, i);
                }
                ins[block_arity] = get_copy(get_irn_n(phi, pos));
@@ -584,7 +570,7 @@ static void construct_ssa_n(ir_node *def, ir_node *user)
 /**
  * Construct SSA for all definitions in arr.
  */
-void construct_ssa_foreach(ir_node **arr, int arr_n)
+static void construct_ssa_foreach(ir_node **arr, int arr_n)
 {
        int i;
        for (i = 0; i < arr_n ; ++i) {
@@ -714,9 +700,6 @@ static ir_node *rawcopy_node(ir_node *node)
 
        arity = get_irn_arity(node);
 
-       /* FIX remove */
-       set_irn_in(cp, arity, get_irn_in(node));
-
        for (i = 0; i < arity; ++i) {
                if (is_backedge(node, i))
                        set_backedge(cp, i);
@@ -1132,7 +1115,7 @@ static void inversion_walk(out_edge *head_entries)
 }
 
 /* Loop peeling */
-void loop_peeling(void)
+static void loop_peeling(void)
 {
        cur_loop_outs = NEW_ARR_F(out_edge, 0);
        irg_walk_graph( current_ir_graph, get_loop_outs, NULL, NULL );
@@ -1150,7 +1133,7 @@ void loop_peeling(void)
 }
 
 /* Loop inversion */
-void loop_inversion(void)
+static void loop_inversion(void)
 {
        unsigned do_inversion = 1;
 
@@ -1209,7 +1192,7 @@ void loop_inversion(void)
  * Returns last element of linked list of copies by
  * walking the linked list.
  */
-ir_node *get_last_copy(ir_node *node)
+static ir_node *get_last_copy(ir_node *node)
 {
        ir_node *copy, *cur;
        cur = node;
@@ -1222,7 +1205,7 @@ ir_node *get_last_copy(ir_node *node)
 /**
  * Rewire floating copies of the current loop.
  */
-void unrolling_fix_cf(void)
+static void unrolling_fix_cf(void)
 {
        ir_node *loophead = loop_cf_head;
        int headarity =         get_irn_arity(loophead);
@@ -1325,7 +1308,7 @@ static ir_node *add_phi(ir_node *node, int phi_pos)
  * Loop unrolling
  * Could be improved with variable range informations.
  */
-void loop_unrolling(void)
+static void loop_unrolling(void)
 {
        int i, j;
 
@@ -1343,18 +1326,35 @@ void loop_unrolling(void)
                out_edge entry = cur_loop_outs[i];
                ir_node *node = entry.node;
                ir_node *pred = get_irn_n(entry.node, entry.pred_irn_n);
+               if (!is_Block(node)) {
+                       for (j = 0; j < unroll_times - 1; ++j) {
+                               copy_walk(pred, is_in_loop, cur_loop);
+                               pred = get_copy(pred);
+                       }
+               }
+       }
 
-               for (j = 0; j < unroll_times - 1; ++j) {
-                       copy_walk(pred, is_in_loop, cur_loop);
-                       if (is_Block(node)) {
+       for (i = 0; i < ARR_LEN(cur_loop_outs); ++i) {
+               out_edge entry = cur_loop_outs[i];
+               ir_node *node = entry.node;
+               ir_node *pred = get_irn_n(entry.node, entry.pred_irn_n);
+
+               if (is_Block(node)) {
+                       for (j = 0; j < unroll_times - 1; ++j) {
+                               copy_walk(pred, is_in_loop, cur_loop);
                                duplicate_preds(node, entry.pred_irn_n, get_copy(pred));
+
+                               pred = get_copy(pred);
                        }
-                       pred = get_copy(pred);
                }
        }
 
        ir_free_resources(current_ir_graph, IR_RESOURCE_IRN_VISITED);
 
+       /*dump_ir_graph(current_ir_graph, "-raw");*/
+
+       /* LDBG 2 */
+#if 1
        /* Line up the floating copies. */
        unrolling_fix_cf();
 
@@ -1370,6 +1370,7 @@ void loop_unrolling(void)
                        construct_ssa_n(pred, node);
                }
        }
+#endif
 
        DEL_ARR_F(cur_loop_outs);