cleanup irouts
[libfirm] / ir / opt / critical_edges.c
index e839f89..392fa26 100644 (file)
@@ -22,7 +22,6 @@
  * @brief    Remove critical edges.
  * @author   Christian Schaefer, Goetz Lindenmaier, Sebastian Felis,
  *           Michael Beck
- * @version  $Id$
  */
 #include "config.h"
 
@@ -46,10 +45,11 @@ typedef struct cf_env {
  * @param n   IR node
  * @param env Environment of walker.
  */
-static void walk_critical_cf_edges(ir_node *n, void *env) {
+static void walk_critical_cf_edges(ir_node *n, void *env)
+{
        int arity, i;
        ir_node *pre, *block, *jmp;
-       cf_env *cenv = env;
+       cf_env *cenv = (cf_env*)env;
        ir_graph *irg = get_irn_irg(n);
 
        /* Block has multiple predecessors */
@@ -68,10 +68,16 @@ static void walk_critical_cf_edges(ir_node *n, void *env) {
 
                        cfop = get_irn_op(skip_Proj(pre));
                        if (is_op_fragile(cfop)) {
-                               if (cenv->ignore_exc_edges && get_Proj_proj(pre) == pn_Generic_X_except)
+                               if (cenv->ignore_exc_edges && is_x_except_Proj(pre))
                                        continue;
                                goto insert;
                        }
+                       if (is_unknown_jump(pre)) {
+                               /* we can't add blocks in between ijmp and its destinations
+                                * TODO: What now, we can't split all critical edges because of this... */
+                               fprintf(stderr, "libfirm warning: Couldn't split all critical edges (compiler will probably fail now)\n");
+                               continue;
+                       }
                        /* we don't want place nodes in the start block, so handle it like forking */
                        if (is_op_forking(cfop) || cfop == op_Start) {
                                /* Predecessor has multiple successors. Insert new control flow edge edges. */
@@ -79,16 +85,17 @@ insert:
                                /* set predecessor of new block */
                                block = new_r_Block(irg, 1, &pre);
                                /* insert new jmp node to new block */
-                               jmp = new_r_Jmp(irg, block);
+                               jmp = new_r_Jmp(block);
                                /* set successor of new block */
                                set_irn_n(n, i, jmp);
                                cenv->changed = 1;
-                       } /* predecessor has multiple successors */
-               } /* for all predecessors */
-       } /* n is a multi-entry block */
+                       }
+               }
+       }
 }
 
-void remove_critical_cf_edges_ex(ir_graph *irg, int ignore_exception_edges) {
+void remove_critical_cf_edges_ex(ir_graph *irg, int ignore_exception_edges)
+{
        cf_env env;
 
        env.ignore_exc_edges = (char)ignore_exception_edges;
@@ -97,13 +104,12 @@ void remove_critical_cf_edges_ex(ir_graph *irg, int ignore_exception_edges) {
        irg_block_walk_graph(irg, NULL, walk_critical_cf_edges, &env);
        if (env.changed) {
                /* control flow changed */
-               set_irg_outs_inconsistent(irg);
-               set_irg_extblk_inconsistent(irg);
-               set_irg_doms_inconsistent(irg);
-               set_irg_loopinfo_inconsistent(irg);
+               clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE);
        }
+       add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES);
 }
 
-void remove_critical_cf_edges(ir_graph *irg) {
+void remove_critical_cf_edges(ir_graph *irg)
+{
        remove_critical_cf_edges_ex(irg, 1);
 }