removed old code artefact
[libfirm] / ir / ir / irgopt.c
index a006f8e..8e306ec 100644 (file)
@@ -34,9 +34,9 @@
 #include "irgraph_t.h"
 #include "irprog_t.h"
 
+#include "iroptimize.h"
 #include "ircons.h"
 #include "iropt_t.h"
-#include "cfopt.h"
 #include "irgopt.h"
 #include "irgmod.h"
 #include "irgwalk.h"
  */
 static void optimize_in_place_wrapper (ir_node *n, void *env) {
        ir_node *optimized = optimize_in_place_2(n);
-       if (optimized != n) exchange (n, optimized);
+       (void) env;
+
+       if (optimized != n) {
+               exchange (n, optimized);
+       }
 }
 
 /**
@@ -111,6 +115,8 @@ void local_optimize_node(ir_node *n) {
  * Block-Walker: uses dominance depth to mark dead blocks.
  */
 static void kill_dead_blocks(ir_node *block, void *env) {
+       (void) env;
+
        if (get_Block_dom_depth(block) < 0) {
                /*
                 * Note that the new dominance code correctly handles
@@ -361,6 +367,7 @@ void
 copy_preds(ir_node *n, void *env) {
        ir_node *nn, *block;
        int i, j, irn_arity;
+       (void) env;
 
        nn = get_new_node(n);
 
@@ -655,6 +662,7 @@ dead_node_elimination(ir_graph *irg) {
 static void relink_bad_block_predecessors(ir_node *n, void *env) {
        ir_node **new_in, *irn;
        int i, new_irn_n, old_irn_arity, new_irn_arity = 0;
+       (void) env;
 
        /* if link field of block is NULL, look for bad predecessors otherwise
           this is already done */
@@ -775,6 +783,7 @@ typedef struct _survive_dce_list_t {
 
 static void dead_node_hook(void *context, ir_graph *irg, int start) {
        survive_dce_t *sd = context;
+       (void) irg;
 
        /* Create a new map before the dead node elimination is performed. */
        if (start) {
@@ -793,6 +802,7 @@ static void dead_node_hook(void *context, ir_graph *irg, int start) {
 static void dead_node_subst_hook(void *context, ir_graph *irg, ir_node *old, ir_node *nw) {
        survive_dce_t *sd = context;
        survive_dce_list_t *list = pmap_get(sd->places, old);
+       (void) irg;
 
        /* If the node is to be patched back, write the new address to all registered locations. */
        if (list) {
@@ -943,6 +953,12 @@ static int can_inline(ir_node *call, ir_graph *called_graph) {
        return res;
 }
 
+enum exc_mode {
+          exc_handler    = 0, /**< There is a handler. */
+          exc_to_end     = 1, /**< Branches to End. */
+          exc_no_handler = 2  /**< Exception handling not represented. */
+};
+
 /* Inlines a method at the given call site. */
 int inline_method(ir_node *call, ir_graph *called_graph) {
        ir_node *pre_call;
@@ -953,7 +969,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
        ir_node **cf_pred;
        ir_node *ret, *phi;
        int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity;
-       int exc_handling;
+       enum exc_mode exc_handling;
        ir_type *called_frame;
        irg_inline_property prop = get_irg_inline_property(called_graph);
 
@@ -1013,13 +1029,13 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
        {
                ir_node *proj, *Mproj = NULL, *Xproj = NULL;
                for (proj = get_irn_link(call); proj; proj = get_irn_link(proj)) {
-                       assert(is_Proj(proj));
-                       if (get_Proj_proj(proj) == pn_Call_X_except) Xproj = proj;
-                       if (get_Proj_proj(proj) == pn_Call_M_except) Mproj = proj;
+                       long proj_nr = get_Proj_proj(proj);
+                       if (proj_nr == pn_Call_X_except) Xproj = proj;
+                       if (proj_nr == pn_Call_M_except) Mproj = proj;
                }
-               if      (Mproj) { assert(Xproj); exc_handling = 0; } /*  Mproj           */
-               else if (Xproj) {                exc_handling = 1; } /* !Mproj &&  Xproj   */
-               else            {                exc_handling = 2; } /* !Mproj && !Xproj   */
+               if      (Mproj) { assert(Xproj); exc_handling = exc_handler; } /*  Mproj           */
+               else if (Xproj) {                exc_handling = exc_to_end; } /* !Mproj &&  Xproj   */
+               else            {                exc_handling = exc_no_handler; } /* !Mproj && !Xproj   */
        }
 
        /* --
@@ -1085,7 +1101,6 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
        /* -- Performing dead node elimination inlines the graph -- */
        /* Copies the nodes to the obstack of current_ir_graph. Updates links to new
           entities. */
-       /* @@@ endless loops are not copied!! -- they should be, I think... */
        irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds,
                 get_irg_frame_type(called_graph));
 
@@ -1121,8 +1136,11 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
 
        /* -- archive keepalives -- */
        irn_arity = get_irn_arity(end);
-       for (i = 0; i < irn_arity; i++)
-               add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
+       for (i = 0; i < irn_arity; i++) {
+               ir_node *ka = get_End_keepalive(end, i);
+               if (! is_Bad(ka))
+                       add_End_keepalive(get_irg_end(current_ir_graph), ka);
+       }
 
        /* The new end node will die.  We need not free as the in array is on the obstack:
           copy_node() only generated 'D' arrays. */
@@ -1141,7 +1159,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
 
        /* -- Build a Tuple for all results of the method.
           Add Phi node if there was more than one Return.  -- */
-       turn_into_tuple(post_call, 4); /* FIXME: is th 4 corrct here ? */
+       turn_into_tuple(post_call, pn_Call_max);
        /* First the Memory-Phi */
        n_ret = 0;
        for (i = 0; i < arity; i++) {
@@ -1184,6 +1202,10 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
        } else {
                set_Tuple_pred(call, pn_Call_T_result, new_Bad());
        }
+
+       /* For now, we cannot inline calls with value_base */
+       set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());
+
        /* Finally the exception control flow.
           We have two (three) possible situations:
           First if the Call branches to an exception handler: We need to add a Phi node to
@@ -1194,14 +1216,15 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
           Second the Call branches to End, the exception is not handled.  Just
           add all inlined exception branches to the End node.
           Third: there is no Exception edge at all. Handle as case two. */
-       if (exc_handling == 0) {
+       if (exc_handling == exc_handler) {
                n_exc = 0;
                for (i = 0; i < arity; i++) {
-                       ir_node *ret;
+                       ir_node *ret, *irn;
                        ret = get_irn_n(end_bl, i);
-                       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
+                       irn = skip_Proj(ret);
+                       if (is_fragile_op(irn) || (get_irn_op(irn) == op_Raise)) {
                                cf_pred[n_exc] = ret;
-                               n_exc++;
+                               ++n_exc;
                        }
                }
                if (n_exc > 0) {
@@ -1229,6 +1252,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
                        set_Tuple_pred(call, pn_Call_X_except, new_Bad());
                        set_Tuple_pred(call, pn_Call_M_except, new_Bad());
                }
+               set_Tuple_pred(call, pn_Call_X_regular, new_Bad());
        } else {
                ir_node *main_end_bl;
                int main_end_bl_arity;
@@ -1238,23 +1262,25 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
                n_exc = 0;
                for (i = 0; i < arity; i++) {
                        ir_node *ret = get_irn_n(end_bl, i);
+                       ir_node *irn = skip_Proj(ret);
 
-                       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
+                       if (is_fragile_op(irn) || (get_irn_op(irn) == op_Raise)) {
                                cf_pred[n_exc] = ret;
                                n_exc++;
                        }
                }
                main_end_bl = get_irg_end_block(current_ir_graph);
                main_end_bl_arity = get_irn_arity(main_end_bl);
-               end_preds =  xmalloc ((n_exc + main_end_bl_arity) * sizeof(*end_preds));
+               end_preds =  xmalloc((n_exc + main_end_bl_arity) * sizeof(*end_preds));
 
                for (i = 0; i < main_end_bl_arity; ++i)
                        end_preds[i] = get_irn_n(main_end_bl, i);
                for (i = 0; i < n_exc; ++i)
                        end_preds[main_end_bl_arity + i] = cf_pred[i];
                set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
-               set_Tuple_pred(call, pn_Call_X_except, new_Bad());
-               set_Tuple_pred(call, pn_Call_M_except, new_Bad());
+               set_Tuple_pred(call, pn_Call_X_regular, new_Bad());
+               set_Tuple_pred(call, pn_Call_X_except,  new_Bad());
+               set_Tuple_pred(call, pn_Call_M_except,  new_Bad());
                free(end_preds);
        }
        free(res_pred);
@@ -1995,6 +2021,54 @@ static void move_out_of_loops(ir_node *n, ir_node *early) {
        }
 }
 
+/* deepest common ancestor in the dominator tree of all nodes'
+   blocks depending on us; our final placement has to dominate DCA. */
+static ir_node *get_deepest_common_ancestor(ir_node *node, ir_node *dca)
+{
+       int i;
+
+       for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
+               ir_node *succ = get_irn_out(node, i);
+               ir_node *succ_blk;
+
+               if (is_End(succ)) {
+                       /*
+                        * This consumer is the End node, a keep alive edge.
+                        * This is not a real consumer, so we ignore it
+                        */
+                       continue;
+               }
+
+               if(is_Proj(succ)) {
+                       dca = get_deepest_common_ancestor(succ, dca);
+               } else {
+                       /* ignore if succ is in dead code */
+                       succ_blk = get_irn_n(succ, -1);
+                       if (is_Block_unreachable(succ_blk))
+                               continue;
+                       dca = consumer_dom_dca(dca, succ, node);
+               }
+       }
+
+       return dca;
+}
+
+static void set_projs_block(ir_node *node, ir_node *block)
+{
+       int i;
+
+       for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
+               ir_node *succ = get_irn_out(node, i);
+
+               assert(is_Proj(succ));
+
+               if(get_irn_mode(succ) == mode_T) {
+                       set_projs_block(succ, block);
+               }
+               set_nodes_block(succ, block);
+       }
+}
+
 /**
  * Find the latest legal block for N and place N into the
  * `optimal' Block between the latest and earliest legal block.
@@ -2054,31 +2128,16 @@ static void place_floats_late(ir_node *n, pdeq *worklist) {
                            (op != op_SymConst) &&
                            (op != op_Proj))
                        {
-                               ir_node *dca = NULL;  /* deepest common ancestor in the
-                                                                                dominator tree of all nodes'
-                                                                                blocks depending on us; our final
-                                                                                placement has to dominate DCA. */
-                               for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
-                                       ir_node *succ = get_irn_out(n, i);
-                                       ir_node *succ_blk;
-
-                                       if (get_irn_op(succ) == op_End) {
-                                               /*
-                                                * This consumer is the End node, a keep alive edge.
-                                                * This is not a real consumer, so we ignore it
-                                                */
-                                               continue;
-                                       }
-
-                                       /* ignore if succ is in dead code */
-                                       succ_blk = get_irn_n(succ, -1);
-                                       if (is_Block_unreachable(succ_blk))
-                                               continue;
-                                       dca = consumer_dom_dca(dca, succ, n);
-                               }
-                               if (dca) {
+                               /* deepest common ancestor in the dominator tree of all nodes'
+                                  blocks depending on us; our final placement has to dominate
+                                  DCA. */
+                               ir_node *dca = get_deepest_common_ancestor(n, NULL);
+                               if (dca != NULL) {
                                        set_nodes_block(n, dca);
                                        move_out_of_loops(n, early_blk);
+                                       if(get_irn_mode(n) == mode_T) {
+                                               set_projs_block(n, get_nodes_block(n));
+                                       }
                                }
                        }
                }