irgmod: Pass the new inputs to turn_into_tuple() instead of initialising them with...
[libfirm] / ir / ana / irscc.c
index aa8b4fb..e97911d 100644 (file)
@@ -25,7 +25,6 @@
  *              Chapter 5.2.1.2.
  * @author   Goetz Lindenmaier
  * @date     7.2002
- * @version  $Id$
  */
 #include "config.h"
 
 #include "irdump.h"
 #include "array.h"
 #include "pmap.h"
-
-/* A variant of the loop tree that avoids loops without head.
-   This reduces the depth of the loop tree. */
-#define NO_LOOPS_WITHOUT_HEAD 1
+#include "ircons.h"
 
 /** The outermost graph the scc is computed for. */
 static ir_graph *outermost_ir_graph;
@@ -58,16 +54,6 @@ static int loop_node_cnt = 0;
 /** Counter to generate depth first numbering of visited nodes. */
 static int current_dfn = 1;
 
-static int max_loop_depth = 0;
-
-void link_to_reg_end(ir_node *n, void *env);
-void set_projx_link(ir_node *cb_projx, ir_node *end_projx);
-ir_node *get_projx_link(ir_node *cb_projx);
-
-/**********************************************************************/
-/* Node attributes                                                   **/
-/**********************************************************************/
-
 /**********************************************************************/
 /* Node attributes needed for the construction.                      **/
 /**********************************************************************/
@@ -76,12 +62,6 @@ typedef struct scc_info {
        int in_stack;          /**< Marks whether node is on the stack. */
        int dfn;               /**< Depth first search number. */
        int uplink;            /**< dfn number of ancestor. */
-       /*  ir_loop *loop;         *//* Refers to the containing loop. */
-       /*
-           struct section *section;
-           xset def;
-           xset use;
-       */
 } scc_info;
 
 /**
@@ -162,36 +142,6 @@ static int get_irn_dfn(ir_node *n)
        return scc->dfn;
 }
 
-#if 0
-static ir_loop *find_nodes_loop(ir_node *n, ir_loop *l)
-{
-       int i;
-       ir_loop *res = NULL;
-
-       /* Test whether n is contained in this loop. */
-       for (i = 0; i < get_loop_n_nodes(l); i++)
-               if (n == get_loop_node(l, i)) return l;
-
-       /* Is this a leave in the loop tree? If so loop not found. */
-       if (get_loop_n_sons(l) == 0) return NULL;
-
-       /* Else descend in the loop tree. */
-       for (i = 0; i < get_loop_n_sons(l); i++) {
-               res = find_nodes_loop(n, get_loop_son(l, i));
-               if (res) break;
-       }
-       return res;
-}
-
-/* @@@ temporary implementation, costly!!! */
-ir_loop * get_irn_loop(ir_node *n)
-{
-       ir_loop *l = get_irg_loop(current_ir_graph);
-       l = find_nodes_loop(n, l);
-       return l;
-}
-#endif
-
 /**********************************************************************/
 /* A stack.                                                          **/
 /**********************************************************************/
@@ -274,7 +224,7 @@ static inline void pop_scc_to_loop(ir_node *n)
    can't they have two loops as sons? Does it never get that far? ) */
 static void close_loop(ir_loop *l)
 {
-       int last = get_loop_n_elements(l) - 1;
+       size_t last = get_loop_n_elements(l) - 1;
        loop_element lelement = get_loop_element(l, last);
        ir_loop *last_son = lelement.son;
 
@@ -318,9 +268,8 @@ static inline void pop_scc_unmark_visit(ir_node *n)
 static ir_loop *new_loop(void)
 {
        ir_loop *father = current_loop;
-       ir_loop *son    = alloc_loop(father, outermost_ir_graph->obst);
+       ir_loop *son    = alloc_loop(father, get_irg_obstack(outermost_ir_graph));
 
-       if (son->depth > max_loop_depth) max_loop_depth = son->depth;
        current_loop = son;
        return father;
 }
@@ -349,9 +298,6 @@ static inline void init_scc(ir_graph *irg, struct obstack *obst)
 {
        init_scc_common();
        irg_walk_graph(irg, init_node, NULL, obst);
-       /*
-       irg_walk (irg, link_to_reg_end, NULL, NULL);
-       */
 }
 
 static inline void finish_scc(void)
@@ -360,7 +306,7 @@ static inline void finish_scc(void)
 }
 
 /**
- * Check weather a given node represents the outer most Start
+ * Check whether a given node represents the outermost Start
  * block. In intra-procedural view this is the start block of the
  * current graph, in interprocedural view it is the start block
  * of the outer most graph.
@@ -383,38 +329,19 @@ static int is_outermost_Start(ir_node *n)
 /* When to walk from nodes to blocks. Only for Control flow operations? */
 static inline int get_start_index(ir_node *n)
 {
-#undef BLOCK_BEFORE_NODE
-#define BLOCK_BEFORE_NODE 1
-
-#if BLOCK_BEFORE_NODE
-
        /* This version assures, that all nodes are ordered absolutely.  This allows
           to undef all nodes in the heap analysis if the block is false, which
           means not reachable.
           I.e., with this code, the order on the loop tree is correct. But a
           (single) test showed the loop tree is deeper. */
-       if (get_irn_op(n) == op_Phi  ||
-           is_Block(n)              ||
+       if (is_Phi(n)   ||
+           is_Block(n) ||
            (get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats &&
              get_irn_pinned(n)              == op_pin_state_floats))
                // Here we could test for backedge at -1 which is illegal
                return 0;
        else
                return -1;
-
-#else
-
-       /* This version causes deeper loop trees (at least we verified this
-          for Polymor).
-          But it guarantees that Blocks are analysed before nodes contained in the
-          block.  If so, we can set the value to undef if the block is not \
-          executed. */
-       if (is_cfop(n) || is_fragile_op(n) || is_Start(n))
-               return -1;
-       else
-               return 0;
-
-#endif
 }
 
 /**
@@ -425,9 +352,7 @@ static inline int get_start_index(ir_node *n)
  */
 static inline int is_possible_loop_head(ir_node *n)
 {
-       ir_op *op = get_irn_op(n);
-       return ((op == op_Block) ||
-               (op == op_Phi));
+       return is_Block(n) || is_Phi(n);
 }
 
 /**
@@ -566,9 +491,6 @@ static ir_node *find_tail(ir_node *n)
        ir_node *m;
        int i, res_index = -2;
 
-       /*
-       if (!icfg && rm_cyclic_phis && remove_cyclic_phis (n)) return NULL;
-        */
        m = stack[tos-1];  /* tos = top of stack */
        if (is_head(m, n)) {
                res_index = smallest_dfn_pred(m, 0);
@@ -609,7 +531,9 @@ static ir_node *find_tail(ir_node *n)
                                                res_index = largest_dfn_pred (m);
                                        break;
                                }
-                               if (m == n) { break; }  /* It's not an unreachable loop, either. */
+                               /* It's not an unreachable loop, either. */
+                               if (m == n)
+                                       break;
                        }
                        //assert(0 && "no head found on stack");
                }
@@ -619,8 +543,10 @@ static ir_node *find_tail(ir_node *n)
                /* It's a completely bad loop: without Phi/Block nodes that can
                   be a head. I.e., the code is "dying".  We break the loop by
                   setting Bad nodes. */
-               int arity = get_irn_arity(n);
-               ir_node *bad = get_irg_bad(get_irn_irg(n));
+               ir_graph *irg   = get_irn_irg(n);
+               ir_mode  *mode  = get_irn_mode(n);
+               ir_node  *bad   = new_r_Bad(irg, mode);
+               int       arity = get_irn_arity(n);
                for (i = -1; i < arity; ++i) {
                        set_irn_n(n, i, bad);
                }
@@ -699,7 +625,6 @@ static void scc(ir_node *n)
                           Next actions: Open a new loop on the loop tree and
                                         try to find inner loops */
 
-#if NO_LOOPS_WITHOUT_HEAD
                        /* This is an adaption of the algorithm from fiasco / optscc to
                         * avoid loops without Block or Phi as first node.  This should
                         * severely reduce the number of evaluations of nodes to detect
@@ -719,9 +644,6 @@ static void scc(ir_node *n)
                                l = current_loop;
                                close = 0;
                        }
-#else
-                       ir_loop *l = new_loop();
-#endif
 
                        /* Remove the loop from the stack ... */
                        pop_scc_unmark_visit(n);
@@ -733,9 +655,7 @@ static void scc(ir_node *n)
                        scc(tail);
 
                        assert(irn_visited(n));
-#if NO_LOOPS_WITHOUT_HEAD
                        if (close)
-#endif
                                close_loop(l);
                } else {
                        /* No loop head was found, that is we have straight line code.
@@ -745,15 +665,12 @@ static void scc(ir_node *n)
        }
 }
 
-/* Constructs backedge information for irg. In interprocedural view constructs
-   backedges for all methods called by irg, too. */
-int construct_backedges(ir_graph *irg)
+void construct_backedges(ir_graph *irg)
 {
        ir_graph *rem = current_ir_graph;
        ir_loop *head_rem;
        struct obstack temp;
 
-       max_loop_depth = 0;
        current_ir_graph   = irg;
        outermost_ir_graph = irg;
 
@@ -772,12 +689,11 @@ int construct_backedges(ir_graph *irg)
        obstack_free(&temp, NULL);
 
        assert(head_rem == current_loop);
-       mature_loops(current_loop, irg->obst);
+       mature_loops(current_loop, get_irg_obstack(irg));
        set_irg_loop(irg, current_loop);
-       set_irg_loopinfo_state(irg, loopinfo_consistent);
+       add_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
        assert(get_irg_loop(irg)->kind == k_ir_loop);
        current_ir_graph = rem;
-       return max_loop_depth;
 }
 
 static void reset_backedges(ir_node *n)
@@ -787,19 +703,6 @@ static void reset_backedges(ir_node *n)
        }
 }
 
-/*
-static void loop_reset_backedges(ir_loop *l)
-{
-       int i;
-       reset_backedges(get_loop_node(l, 0));
-       for (i = 0; i < get_loop_n_nodes(l); ++i)
-               set_irn_loop(get_loop_node(l, i), NULL);
-       for (i = 0; i < get_loop_n_sons(l); ++i) {
-               loop_reset_backedges(get_loop_son(l, i));
-       }
-}
-*/
-
 static void loop_reset_node(ir_node *n, void *env)
 {
        (void) env;
@@ -807,24 +710,17 @@ static void loop_reset_node(ir_node *n, void *env)
        reset_backedges(n);
 }
 
-/** Removes all loop information.
-    Resets all backedges */
 void free_loop_information(ir_graph *irg)
 {
-       /* We can not use this recursion, as the loop might contain
-          illegal nodes by now.  Why else would we throw away the
-          representation?
-       if (get_irg_loop(irg)) loop_reset_backedges(get_irg_loop(irg));
-       */
        irg_walk_graph(irg, loop_reset_node, NULL, NULL);
        set_irg_loop(irg, NULL);
-       set_irg_loopinfo_state(current_ir_graph, loopinfo_none);
+       clear_irg_properties(current_ir_graph, IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
        /* We cannot free the loop nodes, they are on the obstack. */
 }
 
 void free_all_loop_information(void)
 {
-       int i;
+       size_t i;
        for (i = 0; i < get_irp_n_irgs(); i++) {
                free_loop_information(get_irp_irg(i));
        }
@@ -836,7 +732,7 @@ void free_all_loop_information(void)
 
 static int is_loop_variant(ir_loop *l, ir_loop *b)
 {
-       int i, n_elems;
+       size_t i, n_elems;
 
        if (l == b) return 1;
 
@@ -851,14 +747,6 @@ static int is_loop_variant(ir_loop *l, ir_loop *b)
        return 0;
 }
 
-/* Test whether a value is loop invariant.
- *
- * @param n      The node to be tested.
- * @param block  A block node.  We pass the block, not the loop as we must
- *               start off with a block loop to find all proper uses.
- *
- * Returns non-zero, if the node n is not changed in the loop block
- * belongs to or in inner loops of this blocks loop. */
 int is_loop_invariant(const ir_node *n, const ir_node *block)
 {
        ir_loop *l = get_irn_loop(block);