use default error handler if none is specified
[libfirm] / ir / opt / cfopt.c
index 673e448..e9497a5 100644 (file)
@@ -23,9 +23,7 @@
  * @author  Goetz Lindenmaier, Michael Beck, Sebastian Hack
  * @version $Id$
  */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include "iroptimize.h"
 
@@ -45,7 +43,7 @@
 #include "irvrfy.h"
 #include "iredges.h"
 
-#include "array.h"
+#include "array_t.h"
 
 #include "irouts.h"
 #include "irbackedge_t.h"
@@ -165,7 +163,7 @@ static void merge_blocks(ir_node *node, void *ctx) {
                if (!is_Block_dead(b)) {
                        new_block = equivalent_node(b);
 
-                       while (irn_not_visited(b) && (!is_Block_dead(new_block)) && (new_block != b)) {
+                       while (!irn_visited(b) && !is_Block_dead(new_block) && new_block != b) {
                                /* We would have to run gigo() if new is bad, so we
                                   promote it directly below. Nevertheless, we sometimes reach a block
                                   the first time through a dataflow node.  In this case we optimized the
@@ -217,8 +215,10 @@ static void remove_unreachable_blocks_and_conds(ir_node *block, void *env) {
                                set_Block_dead(pred_bl);
                                exchange(pred_X, new_Bad());
                                *changed = 1;
-                       } else if (skipped != pred_X)
+                       } else if (skipped != pred_X) {
                                set_Block_cfgpred(block, i, skipped);
+                               *changed = 1;
+                       }
                }
        }
 
@@ -419,7 +419,7 @@ static void optimize_blocks(ir_node *b, void *ctx) {
        for (i = 0, k = get_Block_n_cfgpreds(b); i < k; ++i) {
                max_preds += test_whether_dispensable(b, i);
        }
-       in = xmalloc(max_preds * sizeof(*in));
+       in = XMALLOCN(ir_node*, max_preds);
 
        /*- Fix the Phi nodes of the current block -*/
        for (phi = get_irn_link(b); phi; ) {
@@ -430,10 +430,9 @@ static void optimize_blocks(ir_node *b, void *ctx) {
                for (i = 0, n = get_Block_n_cfgpreds(b); i < n; ++i) {
                        pred = get_Block_cfgpred_block(b, i);
 
-                       if (is_Bad(get_Block_cfgpred(b, i))) {
+                       if (is_Block_dead(pred)) {
                                /* case Phi 1: Do nothing */
-                       }
-                       else if (is_Block_removable(pred) && Block_not_block_visited(pred)) {
+                       } else if (is_Block_removable(pred) && !Block_block_visited(pred)) {
                                /* case Phi 2: It's an empty block and not yet visited. */
                                ir_node *phi_pred = get_Phi_pred(phi, i);
 
@@ -476,7 +475,7 @@ static void optimize_blocks(ir_node *b, void *ctx) {
        for (k = 0, n = get_Block_n_cfgpreds(b); k < n; ++k) {
                ir_node *predb = get_nodes_block(get_Block_cfgpred(b, k));
 
-               if (is_Block_removable(predb) && Block_not_block_visited(predb)) {
+               if (is_Block_removable(predb) && !Block_block_visited(predb)) {
                        ir_node *next_phi;
 
                        /* we found a predecessor block at position k that will be removed */
@@ -501,9 +500,9 @@ static void optimize_blocks(ir_node *b, void *ctx) {
                                        for (i = 0; i < k; i++) {
                                                pred = get_Block_cfgpred_block(b, i);
 
-                                               if (is_Bad(pred)) {
+                                               if (is_Block_dead(pred)) {
                                                        /* Do nothing */
-                                               } else if (is_Block_removable(pred) && Block_not_block_visited(pred)) {
+                                               } else if (is_Block_removable(pred) && !Block_block_visited(pred)) {
                                                        /* It's an empty block and not yet visited. */
                                                        for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
                                                                if (! is_Bad(get_Block_cfgpred(pred, j)))
@@ -523,11 +522,11 @@ static void optimize_blocks(ir_node *b, void *ctx) {
 
                                        /* and now all the rest */
                                        for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
-                                               pred = get_nodes_block(get_Block_cfgpred(b, i));
+                                               pred = get_Block_cfgpred_block(b, i);
 
-                                               if (is_Bad(get_Block_cfgpred(b, i))) {
+                                               if (is_Block_dead(pred)) {
                                                        /* Do nothing */
-                                               } else if (is_Block_removable(pred) && Block_not_block_visited(pred)) {
+                                               } else if (is_Block_removable(pred) && !Block_block_visited(pred)) {
                                                        /* It's an empty block and not yet visited. */
                                                        for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
                                                                if (! is_Bad(get_Block_cfgpred(pred, j)))
@@ -557,19 +556,19 @@ static void optimize_blocks(ir_node *b, void *ctx) {
        for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
                pred = get_Block_cfgpred_block(b, i);
 
-               if (is_Bad(pred)) {
+               if (is_Block_dead(pred)) {
                        /* case 1: Do nothing */
-               } else if (is_Block_removable(pred) && Block_not_block_visited(pred)) {
+               } else if (is_Block_removable(pred) && !Block_block_visited(pred)) {
                        /* case 2: It's an empty block and not yet visited. */
                        assert(get_Block_n_cfgpreds(b) > 1);
                        /* Else it should be optimized by equivalent_node. */
                        for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
-                               ir_node *pred_block = get_Block_cfgpred(pred, j);
+                               ir_node *pred_X = get_Block_cfgpred(pred, j);
 
                                /* because of breaking loops, not all predecessors are Bad-clean,
                                 * so we must check this here again */
-                               if (! is_Bad(pred_block))
-                                       in[n_preds++] = pred_block;
+                               if (! is_Bad(pred_X))
+                                       in[n_preds++] = pred_X;
                        }
                        /* Remove block as it might be kept alive. */
                        exchange(pred, b/*new_Bad()*/);
@@ -710,7 +709,7 @@ void optimize_cf(ir_graph *irg) {
        edges_deactivate(irg);
 
        /* we use the mark flag to mark removable blocks */
-       set_using_block_mark(irg);
+       ir_reserve_resources(irg, IR_RESOURCE_BLOCK_MARK);
 restart:
        env.changed    = 0;
        env.phis_moved = 0;
@@ -726,7 +725,7 @@ restart:
 
                if (is_Block(ka)) {
                        /* do NOT keep dead blocks */
-                       if (get_Block_dom_depth(ka) < 0) {
+                       if (is_Block_dead(ka) || get_Block_dom_depth(ka) < 0) {
                                set_End_keepalive(end, i, new_Bad());
                                env.changed = 1;
                        }
@@ -738,12 +737,12 @@ restart:
                }
        }
 
-       set_using_irn_link(irg);
+       ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
 
        env.list = plist_new();
        irg_walk(end, merge_blocks, collect_nodes, &env);
 
-       clear_using_irn_link(irg);
+       ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
 
        if (env.changed) {
                /* Handle graph state if was changed. */
@@ -780,30 +779,26 @@ restart:
 
        /* in rare cases a node may be kept alive more than once, use the visited flag to detect this */
        inc_irg_visited(irg);
-       set_using_irn_visited(irg);
+       ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
 
        /* fix the keep alive */
        for (i = j = 0; i < n; i++) {
                ir_node *ka = get_End_keepalive(end, i);
 
-               if (irn_not_visited(ka)) {
-                       ir_op *op = get_irn_op(ka);
-
-                       if ((op == op_Block) && Block_not_block_visited(ka)) {
-                               /* irg_block_walk() will increase the block visited flag, but we must visit only
-                                  these blocks that are not visited yet, so decrease it first. */
-                               set_irg_block_visited(irg, get_irg_block_visited(irg) - 1);
-                               irg_block_walk(ka, optimize_blocks, remove_simple_blocks, &env.changed);
-                               mark_irn_visited(ka);
-                               in[j++] = ka;
-                       } else if (op == op_Phi) {
-                               mark_irn_visited(ka);
-                               /* don't keep alive dead blocks */
-                               if (! is_Block_dead(get_nodes_block(ka)))
+               if (!irn_visited(ka)) {
+                       if (is_Block(ka)) {
+                               if (!Block_block_visited(ka)) {
+                                       /* irg_block_walk() will increase the block visited flag, but we must visit only
+                                          these blocks that are not visited yet, so decrease it first. */
+                                       set_irg_block_visited(irg, get_irg_block_visited(irg) - 1);
+                                       irg_block_walk(ka, optimize_blocks, remove_simple_blocks, &env.changed);
+                                       mark_irn_visited(ka);
                                        in[j++] = ka;
-                       } else if (is_op_keep(op)) {
+                               }
+                       } else {
                                mark_irn_visited(ka);
-                               if (! is_Block_dead(get_nodes_block(ka)))
+                               /* don't keep alive dead blocks */
+                               if (!is_Bad(ka) && !is_Block_dead(get_nodes_block(ka)))
                                        in[j++] = ka;
                        }
                }
@@ -813,8 +808,7 @@ restart:
                env.changed = 1;
        }
 
-       clear_using_block_mark(irg);
-       clear_using_irn_visited(irg);
+       ir_free_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_IRN_VISITED);
 
        if (env.phis_moved) {
                /* Bad: when we moved Phi's, we might produce dead Phi nodes