fix backend Cond/Cmp flag optimization failing for unoptimized code
[libfirm] / ir / opt / code_placement.c
index 72fbdb9..0d633ca 100644 (file)
@@ -23,7 +23,6 @@
  *           often.
  * @author   Christian Schaefer, Goetz Lindenmaier, Sebastian Felis,
  *           Michael Beck
- * @version  $Id$
  *
  * The idea here is to push nodes as deep into the dominance tree as their
  * dependencies allow. After pushing them back up out of as many loops as
@@ -39,6 +38,7 @@
 #include "irouts.h"
 #include "irgopt.h"
 #include "irpass.h"
+#include "opt_manage.h"
 
 static bool is_block_reachable(ir_node *block)
 {
@@ -95,10 +95,6 @@ static void place_floats_early(ir_node *n, waitq *worklist)
        }
 
        block = get_nodes_block(n);
-       /* do not move unreachable code (or its predecessors around) since dominance
-        * is inalid there */
-       if (!is_block_reachable(block))
-               return;
 
        /* first move predecessors up */
        arity = get_irn_arity(n);
@@ -215,8 +211,8 @@ static ir_node *consumer_dom_dca(ir_node *dca, ir_node *consumer,
                                if (is_Bad(new_block))
                                        continue;
 
-                               if (is_block_reachable(new_block))
-                                       dca = calc_dom_dca(dca, new_block);
+                               assert(is_block_reachable(new_block));
+                               dca = calc_dom_dca(dca, new_block);
                        }
                }
        } else {
@@ -285,10 +281,7 @@ static ir_node *get_deepest_common_dom_ancestor(ir_node *node, ir_node *dca)
                         * the users of Proj are our users. */
                        dca = get_deepest_common_dom_ancestor(succ, dca);
                } else {
-                       /* ignore successors in unreachable code */
-                       ir_node *succ_blk = get_nodes_block(succ);
-                       if (!is_block_reachable(succ_blk))
-                               continue;
+                       assert(is_block_reachable(get_nodes_block(succ)));
                        dca = consumer_dom_dca(dca, succ, node);
                }
        }
@@ -364,10 +357,8 @@ static void place_floats_late(ir_node *n, pdeq *worklist)
                return;
        }
 
-       /* don't move unreachable code around */
        block = get_nodes_block(n);
-       if (!is_block_reachable(block))
-               return;
+       assert(is_block_reachable(block));
 
        /* deepest common ancestor in the dominator tree of all nodes'
           blocks depending on us; our final placement has to dominate
@@ -405,23 +396,21 @@ static void place_late(ir_graph *irg, waitq *worklist)
 }
 
 /* Code Placement. */
-void place_code(ir_graph *irg)
+static ir_graph_state_t do_codeplacement(ir_graph *irg)
 {
        waitq *worklist;
 
-       remove_critical_cf_edges(irg);
-
        /* Handle graph state */
        assert(get_irg_phase_state(irg) != phase_building);
-       assure_irg_outs(irg);
-       assure_doms(irg);
-       assure_cf_loop(irg);
 
        /* Place all floating nodes as early as possible. This guarantees
         a legal code placement. */
        worklist = new_waitq();
        place_early(irg, worklist);
 
+       /* While GCSE might place nodes in unreachable blocks,
+        * these are now placed in reachable blocks. */
+
        /* Note: place_early changes only blocks, no data edges. So, the
         * data out edges are still valid, no need to recalculate them here. */
 
@@ -429,8 +418,22 @@ void place_code(ir_graph *irg)
           unnecessary executions of the node. */
        place_late(irg, worklist);
 
-       set_irg_loopinfo_inconsistent(irg);
        del_waitq(worklist);
+       return 0;
+}
+
+static optdesc_t opt_codeplacement = {
+       "code-placement",
+       IR_GRAPH_STATE_NO_CRITICAL_EDGES |
+       IR_GRAPH_STATE_CONSISTENT_OUTS |
+       IR_GRAPH_STATE_CONSISTENT_DOMINANCE |
+       IR_GRAPH_STATE_CONSISTENT_LOOPINFO,
+       do_codeplacement,
+};
+
+void place_code(ir_graph *irg)
+{
+       perform_irg_optimization(irg, &opt_codeplacement);
 }
 
 /**
@@ -444,6 +447,26 @@ static void place_code_wrapper(ir_graph *irg)
        set_opt_global_cse(0);
 }
 
+#if 0
+static ir_graph_state_t do_gcse(ir_graph *irg)
+{
+       set_opt_global_cse(1);
+       optimize_graph_df(irg);
+       do_codeplacement(irg);
+       set_opt_global_cse(0);
+       return 0;
+}
+
+static optdesc_t opt_gcse = {
+       "gcse",
+       IR_GRAPH_STATE_NO_CRITICAL_EDGES |
+       IR_GRAPH_STATE_CONSISTENT_OUTS |
+       IR_GRAPH_STATE_CONSISTENT_DOMINANCE |
+       IR_GRAPH_STATE_CONSISTENT_LOOPINFO,
+       do_gcse,
+};
+#endif
+
 ir_graph_pass_t *place_code_pass(const char *name)
 {
        return def_graph_pass(name ? name : "place", place_code_wrapper);