BugFix: equivalent_node_Bound() was too greedy, reduced to a safe minimum (now mostly...
[libfirm] / ir / ir / irgopt.c
index 84493f0..ad794eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -182,15 +182,13 @@ static void opt_walker(ir_node *n, void *env) {
 /* Applies local optimizations to all nodes in the graph until fixpoint. */
 void optimize_graph_df(ir_graph *irg) {
        pdeq     *waitq = new_pdeq();
-       int      state = edges_activated(irg);
        ir_graph *rem = current_ir_graph;
        ir_node  *end;
-       int      i;
+       int      i, state;
 
        current_ir_graph = irg;
 
-       if (! state)
-               edges_activate(irg);
+       state = edges_assure(irg);
 
        if (get_opt_global_cse())
                set_irg_pinned(current_ir_graph, op_pin_state_floats);
@@ -341,9 +339,13 @@ static void copy_node(ir_node *n, void *env) {
                get_irn_mode(n),
                new_arity,
                get_irn_in(n) + 1);
-               /* Copy the attributes.  These might point to additional data.  If this
-               was allocated on the old obstack the pointers now are dangling.  This
-       frees e.g. the memory of the graph_arr allocated in new_immBlock. */
+       /* Copy the attributes.  These might point to additional data.  If this
+          was allocated on the old obstack the pointers now are dangling.  This
+          frees e.g. the memory of the graph_arr allocated in new_immBlock. */
+       if (op == op_Block) {
+               /* we cannot allow blocks WITHOUT macroblock input */
+               set_irn_n(nn, -1, get_irn_n(n, -1));
+       }
        copy_node_attr(n, nn);
 
 #ifdef DEBUG_libfirm
@@ -380,7 +382,9 @@ static void copy_preds(ir_node *n, void *env) {
                        set_irn_n(nn, -1, nn);
                } else {
                        /* get the macro block header */
-                       set_irn_n(nn, -1, get_new_node(mbh));
+                       ir_node *nmbh = get_new_node(mbh);
+                       assert(nmbh != NULL);
+                       set_irn_n(nn, -1, nmbh);
                }
 
                /* Don't copy Bad nodes. */
@@ -1342,7 +1346,7 @@ static ir_graph *get_call_called_irg(ir_node *call) {
        ir_graph *called_irg = NULL;
 
        addr = get_Call_ptr(call);
-       if (is_SymConst(addr) && get_SymConst_kind(addr) == symconst_addr_ent) {
+       if (is_SymConst_addr_ent(addr)) {
                called_irg = get_entity_irg(get_SymConst_entity(addr));
        }
 
@@ -2220,7 +2224,8 @@ void place_code(ir_graph *irg) {
 }
 
 typedef struct cf_env {
-       char changed;       /**< flag indicates that the cf graphs has changed. */
+       char ignore_exc_edges; /**< set if exception edges should be ignored. */
+       char changed;          /**< flag indicates that the cf graphs has changed. */
 } cf_env;
 
 /**
@@ -2248,12 +2253,15 @@ static void walk_critical_cf_edges(ir_node *n, void *env) {
                        const ir_op *cfop;
 
                        pre = get_irn_n(n, i);
-                       cfop = get_irn_op(skip_Proj(pre));
+                       /* don't count Bad's */
+                       if (is_Bad(pre))
+                               continue;
 
+                       cfop = get_irn_op(skip_Proj(pre));
                        if (is_op_fragile(cfop)) {
-                               if (cfop != op_Raise)
-                                       goto insert;
-                               continue;
+                               if (cenv->ignore_exc_edges && get_Proj_proj(pre) == pn_Generic_X_except)
+                                       continue;
+                               goto insert;
                        }
                        /* we don't want place nodes in the start block, so handle it like forking */
                        if (is_op_forking(cfop) || cfop == op_Start) {
@@ -2274,7 +2282,8 @@ insert:
 void remove_critical_cf_edges(ir_graph *irg) {
        cf_env env;
 
-       env.changed = 0;
+       env.ignore_exc_edges = 1;
+       env.changed          = 0;
 
        irg_block_walk_graph(irg, NULL, walk_critical_cf_edges, &env);
        if (env.changed) {