used ircons_t.h now
[libfirm] / ir / ir / irgopt.c
index 406cf2e..7798f0f 100644 (file)
@@ -24,7 +24,7 @@
 # include "irgraph_t.h"
 # include "iropt_t.h"
 # include "irgwalk.h"
-# include "ircons.h"
+# include "ircons_t.h"
 # include "irgmod.h"
 # include "array.h"
 # include "pset.h"
@@ -35,6 +35,7 @@
 # include "irbackedge_t.h"
 # include "irflag_t.h"
 # include "firmstat.h"
+# include "cgana.h"
 
 /* Defined in iropt.c */
 pset *new_identities (void);
@@ -95,6 +96,8 @@ local_optimize_graph (ir_graph *irg) {
     set_irg_outs_inconsistent(current_ir_graph);
   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
     set_irg_dom_inconsistent(current_ir_graph);
+  set_irg_loopinfo_inconsistent(current_ir_graph);
+
 
   /* Clean the value_table in irg for the cse. */
   del_identities(irg->value_table);
@@ -188,13 +191,16 @@ static void
 copy_node (ir_node *n, void *env) {
   ir_node *nn, *block;
   int new_arity;
-
+  opcode op = get_irn_opcode(n);
   /* The end node looses it's flexible in array.  This doesn't matter,
      as dead node elimination builds End by hand, inlineing doesn't use
      the End node. */
   /* assert(n->op == op_End ||  ((_ARR_DESCR(n->in))->cookie != ARR_F_MAGIC)); */
 
-  if (get_irn_opcode(n) == iro_Block) {
+  if (op == iro_Bad) {
+    /* node copied already */
+    return;
+  } else if (op == iro_Block) {
     block = NULL;
     new_arity = compute_new_arity(n);
     n->attr.block.graph_arr = NULL;
@@ -260,8 +266,16 @@ copy_preds (ir_node *n, void *env) {
        that the fields in ir_graph are set properly. */
     if ((get_opt_control_flow_straightening()) &&
     (get_Block_n_cfgpreds(nn) == 1) &&
-    (get_irn_op(get_Block_cfgpred(nn, 0)) == op_Jmp))
-      exchange(nn, get_nodes_Block(get_Block_cfgpred(nn, 0)));
+    (get_irn_op(get_Block_cfgpred(nn, 0)) == op_Jmp)) {
+      ir_node *old = get_nodes_Block(get_Block_cfgpred(nn, 0));
+      if (nn == old) {
+    /* Jmp jumps into the block it is in -- deal self cycle. */
+    assert(is_Bad(get_new_node(get_irg_bad(current_ir_graph))));
+    exchange(nn, get_new_node(get_irg_bad(current_ir_graph)));
+      } else {
+    exchange(nn, old);
+      }
+    }
   } else if (get_irn_opcode(n) == iro_Phi) {
     /* Don't copy node if corresponding predecessor in block is Bad.
        The Block itself should not be Bad. */
@@ -298,7 +312,7 @@ copy_preds (ir_node *n, void *env) {
  */
 static void
 copy_graph (void) {
-  ir_node *oe, *ne; /* old end, new end */
+  ir_node *oe, *ne, *ob, *nb; /* old end, new end, old bad, new bad */
   ir_node *ka;      /* keep alive */
   int i, irn_arity;
 
@@ -315,10 +329,21 @@ copy_graph (void) {
   copy_attrs(oe, ne);
   set_new_node(oe, ne);
 
+  ob = get_irg_bad(current_ir_graph);
+  nb =  new_ir_node(get_irn_dbg_info(ob),
+           current_ir_graph,
+           NULL,
+           op_Bad,
+           mode_T,
+           0,
+           NULL);
+  set_new_node(ob, nb);
+
   /* copy the live nodes */
   irg_walk(get_nodes_Block(oe), copy_node, copy_preds, NULL);
   /* copy_preds for the end node ... */
   set_nodes_Block(ne, get_new_node(get_nodes_Block(oe)));
+  set_nodes_Block(nb, get_new_node(get_nodes_Block(ob)));
 
   /*- ... and now the keep alives. -*/
   /* First pick the not marked block nodes and walk them.  We must pick these
@@ -362,9 +387,10 @@ copy_graph_env (void) {
   /* Not all nodes remembered in current_ir_graph might be reachable
      from the end node.  Assure their link is set to NULL, so that
      we can test whether new nodes have been computed. */
-  set_irn_link(get_irg_frame  (current_ir_graph), NULL);
-  set_irn_link(get_irg_globals(current_ir_graph), NULL);
-  set_irn_link(get_irg_args   (current_ir_graph), NULL);
+  set_irn_link(get_irg_frame      (current_ir_graph), NULL);
+  set_irn_link(get_irg_globals    (current_ir_graph), NULL);
+  set_irn_link(get_irg_args       (current_ir_graph), NULL);
+  set_irn_link(get_irg_initial_mem(current_ir_graph), NULL);
 
   /* we use the block walk flag for removing Bads from Blocks ins. */
   inc_irg_block_visited(current_ir_graph);
@@ -374,7 +400,7 @@ copy_graph_env (void) {
 
   /* fix the fields in current_ir_graph */
   old_end = get_irg_end(current_ir_graph);
-  set_irg_end (current_ir_graph, get_new_node(old_end));
+  set_irg_end        (current_ir_graph, get_new_node(old_end));
   set_irg_end_except (current_ir_graph, get_irg_end(current_ir_graph));
   set_irg_end_reg    (current_ir_graph, get_irg_end(current_ir_graph));
   free_End(old_end);
@@ -387,29 +413,28 @@ copy_graph_env (void) {
     copy_node (get_irg_globals(current_ir_graph), NULL);
     copy_preds(get_irg_globals(current_ir_graph), NULL);
   }
+  if (get_irn_link(get_irg_initial_mem(current_ir_graph)) == NULL) {
+    copy_node (get_irg_initial_mem(current_ir_graph), NULL);
+    copy_preds(get_irg_initial_mem(current_ir_graph), NULL);
+  }
   if (get_irn_link(get_irg_args(current_ir_graph)) == NULL) {
     copy_node (get_irg_args(current_ir_graph), NULL);
     copy_preds(get_irg_args(current_ir_graph), NULL);
   }
-  set_irg_start  (current_ir_graph, get_new_node(get_irg_start(current_ir_graph)));
+  set_irg_start      (current_ir_graph, get_new_node(get_irg_start(current_ir_graph)));
 
   set_irg_start_block(current_ir_graph,
               get_new_node(get_irg_start_block(current_ir_graph)));
-  set_irg_frame  (current_ir_graph, get_new_node(get_irg_frame(current_ir_graph)));
-  set_irg_globals(current_ir_graph, get_new_node(get_irg_globals(current_ir_graph)));
-  set_irg_args   (current_ir_graph, get_new_node(get_irg_args(current_ir_graph)));
+  set_irg_frame      (current_ir_graph, get_new_node(get_irg_frame(current_ir_graph)));
+  set_irg_globals    (current_ir_graph, get_new_node(get_irg_globals(current_ir_graph)));
+  set_irg_initial_mem(current_ir_graph, get_new_node(get_irg_initial_mem(current_ir_graph)));
+  set_irg_args       (current_ir_graph, get_new_node(get_irg_args(current_ir_graph)));
+
   if (get_irn_link(get_irg_bad(current_ir_graph)) == NULL) {
     copy_node(get_irg_bad(current_ir_graph), NULL);
     copy_preds(get_irg_bad(current_ir_graph), NULL);
   }
   set_irg_bad(current_ir_graph, get_new_node(get_irg_bad(current_ir_graph)));
-  /* GL removed: we need unknown with mode for analyses.
-  if (get_irn_link(get_irg_unknown(current_ir_graph)) == NULL) {
-    copy_node(get_irg_unknown(current_ir_graph), NULL);
-    copy_preds(get_irg_unknown(current_ir_graph), NULL);
-  }
-  set_irg_unknown(current_ir_graph, get_new_node(get_irg_unknown(current_ir_graph)));
-  */
 }
 
 /**
@@ -420,7 +445,6 @@ copy_graph_env (void) {
  * Adds all new nodes to a new hash table for cse.  Does not
  * perform cse, so the hash table might contain common subexpressions.
  */
-/* Amroq call this emigrate() */
 void
 dead_node_elimination(ir_graph *irg) {
   ir_graph *rem;
@@ -428,6 +452,7 @@ dead_node_elimination(ir_graph *irg) {
   struct obstack *graveyard_obst = NULL;
   struct obstack *rebirth_obst   = NULL;
 
+  /* inform statistics that we started a dead-node elimination run */
   stat_dead_node_elim_start(irg);
 
   /* Remember external state of current_ir_graph. */
@@ -437,9 +462,8 @@ dead_node_elimination(ir_graph *irg) {
 
   /* Handle graph state */
   assert(get_irg_phase_state(current_ir_graph) != phase_building);
-  assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none);
+  free_callee_info(current_ir_graph);
   free_outs(current_ir_graph);
-
   /* @@@ so far we loose loops when copying */
   free_loop_information(current_ir_graph);
 
@@ -466,6 +490,7 @@ dead_node_elimination(ir_graph *irg) {
     xfree (graveyard_obst);           /* ... then free it.           */
   }
 
+  /* inform statistics that the run is over */
   stat_dead_node_elim_stop(irg);
 
   current_ir_graph = rem;
@@ -660,7 +685,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
   irg_inline_property prop = get_irg_inline_property(called_graph);
 
   if ( (prop != irg_inline_forced) && (!get_opt_optimize() || !get_opt_inline() ||
-      (prop == irg_inline_forbidden))) return 0;
+                                       (prop == irg_inline_forbidden))) return 0;
 
 
   /*
@@ -681,6 +706,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
   assert(get_irg_pinned(called_graph) == pinned);
   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
     set_irg_outs_inconsistent(current_ir_graph);
+  set_irg_loopinfo_inconsistent(current_ir_graph);
 
   /* -- Check preconditions -- */
   assert(get_irn_op(call) == op_Call);
@@ -701,8 +727,8 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
   /* -- Decide how to handle exception control flow: Is there a handler
      for the Call node, or do we branch directly to End on an exception?
      exc_handling: 0 There is a handler.
-                   1 Branches to End.
-           2 Exception handling not represented in Firm. -- */
+     1 Branches to End.
+     2 Exception handling not represented in Firm. -- */
   {
     ir_node *proj, *Mproj = NULL, *Xproj = NULL;
     for (proj = (ir_node *)get_irn_link(call); proj; proj = (ir_node *)get_irn_link(proj)) {
@@ -717,9 +743,9 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
 
 
   /* --
-      the procedure and later replaces the Start node of the called graph.
-      Post_call is the old Call node and collects the results of the called
-      graph. Both will end up being a tuple.  -- */
+     the procedure and later replaces the Start node of the called graph.
+     Post_call is the old Call node and collects the results of the called
+     graph. Both will end up being a tuple.  -- */
   post_bl = get_nodes_Block(call);
   set_irg_current_block(current_ir_graph, post_bl);
   /* XxMxPxP of Start + parameter of Call */
@@ -733,8 +759,8 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
   post_call = call;
 
   /* --
-      The new block gets the ins of the old block, pre_call and all its
-      predecessors and all Phi nodes. -- */
+     The new block gets the ins of the old block, pre_call and all its
+     predecessors and all Phi nodes. -- */
   part_block(pre_call);
 
   /* -- Prepare state for dead node elimination -- */
@@ -750,12 +776,11 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
      Further mark these nodes so that they are not visited by the
      copying. */
   set_irn_link(get_irg_start(called_graph), pre_call);
-  set_irn_visited(get_irg_start(called_graph),
-          get_irg_visited(current_ir_graph));
-  set_irn_link(get_irg_start_block(called_graph),
-           get_nodes_Block(pre_call));
-  set_irn_visited(get_irg_start_block(called_graph),
-          get_irg_visited(current_ir_graph));
+  set_irn_visited(get_irg_start(called_graph), get_irg_visited(current_ir_graph));
+  set_irn_link(get_irg_start_block(called_graph), get_nodes_Block(pre_call));
+  set_irn_visited(get_irg_start_block(called_graph), get_irg_visited(current_ir_graph));
+  set_irn_link(get_irg_bad(called_graph), get_irg_bad(current_ir_graph));
+  set_irn_visited(get_irg_bad(called_graph), get_irg_visited(current_ir_graph));
 
   /* Initialize for compaction of in arrays */
   inc_irg_block_visited(current_ir_graph);
@@ -780,7 +805,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
      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));
+           get_irg_frame_type(called_graph));
 
   /* Repair called_graph */
   set_irg_visited(called_graph, get_irg_visited(current_ir_graph));
@@ -790,12 +815,12 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
   /* -- Merge the end of the inlined procedure with the call site -- */
   /* We will turn the old Call node into a Tuple with the following
      predecessors:
-       -1:  Block of Tuple.
-       0: Phi of all Memories of Return statements.
-       1: Jmp from new Block that merges the control flow from all exception
-      predecessors of the old end block.
-       2: Tuple of all arguments.
-       3: Phi of Exception memories.
+     -1:  Block of Tuple.
+     0: Phi of all Memories of Return statements.
+     1: Jmp from new Block that merges the control flow from all exception
+     predecessors of the old end block.
+     2: Tuple of all arguments.
+     3: Phi of Exception memories.
      In case the old Call directly branches to End on an exception we don't
      need the block merging all exceptions nor the Phi of the exception
      memories.
@@ -856,18 +881,21 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
     for (j = 0; j < n_res; j++) {
       n_ret = 0;
       for (i = 0; i < arity; i++) {
-       ret = get_irn_n(end_bl, i);
-       if (get_irn_op(ret) == op_Return) {
-         cf_pred[n_ret] = get_Return_res(ret, j);
-         n_ret++;
-       }
+        ret = get_irn_n(end_bl, i);
+        if (get_irn_op(ret) == op_Return) {
+          cf_pred[n_ret] = get_Return_res(ret, j);
+          n_ret++;
+        }
       }
-      phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0]));
+      if (n_ret > 0)
+       phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0]));
+      else
+       phi = new_Bad();
       res_pred[j] = phi;
       /* Conserve Phi-list for further inlinings -- but might be optimized */
       if (get_nodes_Block(phi) == post_bl) {
-       set_irn_link(phi, get_irn_link(post_bl));
-       set_irn_link(post_bl, phi);
+        set_irn_link(phi, get_irn_link(post_bl));
+        set_irn_link(post_bl, phi);
       }
     }
     set_Tuple_pred(call, pn_Call_T_result, new_Tuple(n_res, res_pred));
@@ -890,8 +918,8 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
       ir_node *ret;
       ret = get_irn_n(end_bl, i);
       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
-    cf_pred[n_exc] = ret;
-    n_exc++;
+        cf_pred[n_exc] = ret;
+        n_exc++;
       }
     }
     if (n_exc > 0) {
@@ -900,19 +928,19 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
       /* The Phi for the memories with the exception objects */
       n_exc = 0;
       for (i = 0; i < arity; i++) {
-    ir_node *ret;
-    ret = skip_Proj(get_irn_n(end_bl, i));
-    if (get_irn_op(ret) == op_Call) {
-      cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 3);
-      n_exc++;
-    } else if (is_fragile_op(ret)) {
-    /* We rely that all cfops have the memory output at the same position. */
-      cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 0);
-      n_exc++;
-    } else if (get_irn_op(ret) == op_Raise) {
-      cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 1);
-      n_exc++;
-    }
+        ir_node *ret;
+        ret = skip_Proj(get_irn_n(end_bl, i));
+        if (get_irn_op(ret) == op_Call) {
+          cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 3);
+          n_exc++;
+        } else if (is_fragile_op(ret)) {
+          /* We rely that all cfops have the memory output at the same position. */
+          cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 0);
+          n_exc++;
+        } else if (get_irn_op(ret) == op_Raise) {
+          cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 1);
+          n_exc++;
+        }
       }
       set_Tuple_pred(call, pn_Call_M_except, new_Phi(n_exc, cf_pred, mode_M));
     } else {
@@ -966,14 +994,14 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
     for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
       cf_op = get_Block_cfgpred(end_bl, i);
       if (get_irn_op(cf_op) == op_Proj) {
-    cf_op = get_Proj_pred(cf_op);
-    if ((get_irn_op(cf_op) == op_Tuple) && (cf_op == call)) {
-      /*  There are unoptimized tuples from inlineing before when no exc */
-      assert(get_Proj_proj(get_Block_cfgpred(end_bl, i)) == pn_Call_X_except);
-      cf_op = get_Tuple_pred(cf_op, pn_Call_X_except);
-      assert(get_irn_op(cf_op) == op_Jmp);
-      break;
-    }
+        cf_op = get_Proj_pred(cf_op);
+        if ((get_irn_op(cf_op) == op_Tuple) && (cf_op == call)) {
+          /*  There are unoptimized tuples from inlineing before when no exc */
+          assert(get_Proj_proj(get_Block_cfgpred(end_bl, i)) == pn_Call_X_except);
+          cf_op = get_Tuple_pred(cf_op, pn_Call_X_except);
+          assert(get_irn_op(cf_op) == op_Jmp);
+          break;
+        }
       }
     }
     /* repair */
@@ -982,11 +1010,11 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
       arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
       cf_pred = (ir_node **) malloc (arity * sizeof (ir_node *));
       for (j = 0; j < i; j++)
-    cf_pred[j] = get_Block_cfgpred(end_bl, j);
+        cf_pred[j] = get_Block_cfgpred(end_bl, j);
       for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
-    cf_pred[j] = get_Block_cfgpred(bl, j-i);
+        cf_pred[j] = get_Block_cfgpred(bl, j-i);
       for (j = j; j < arity; j++)
-    cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
+        cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
       set_irn_in(end_bl, arity, cf_pred);
       free(cf_pred);
       /*  Remove the exception pred from post-call Tuple. */
@@ -1078,7 +1106,7 @@ void inline_small_irgs(ir_graph *irg, int size) {
   current_ir_graph = irg;
   /* Handle graph state */
   assert(get_irg_phase_state(current_ir_graph) != phase_building);
-  assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none);
+  free_callee_info(current_ir_graph);
 
   /* Find Call nodes to inline.
      (We can not inline during a walk of the graph, as inlineing the same
@@ -1195,7 +1223,7 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
   for (i = 0; i < n_irgs; ++i) {
     current_ir_graph = get_irp_irg(i);
     assert(get_irg_phase_state(current_ir_graph) != phase_building);
-    assert(get_irg_callee_info_state(current_ir_graph) == irg_callee_info_none);
+    free_callee_info(current_ir_graph);
 
     irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2,
          get_irg_link(current_ir_graph));
@@ -1236,12 +1264,12 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
 /*         get_entity_name(get_irg_entity(callee))); */
           if (inline_method(call, callee)) {
             did_inline = 1;
-           env->n_call_nodes--;
-           eset_insert_all(env->call_nodes, callee_env->call_nodes);
-           env->n_call_nodes += callee_env->n_call_nodes;
-           env->n_nodes += callee_env->n_nodes;
-           callee_env->n_callers--;
-         }
+        env->n_call_nodes--;
+        eset_insert_all(env->call_nodes, callee_env->call_nodes);
+        env->n_call_nodes += callee_env->n_call_nodes;
+        env->n_nodes += callee_env->n_nodes;
+        callee_env->n_callers--;
+      }
         } else {
           eset_insert(env->call_nodes, call);
         }
@@ -1278,13 +1306,13 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
 /*       printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)), */
 /*       get_entity_name(get_irg_entity(callee))); */
         if (inline_method(call, callee)) {
-         did_inline = 1;
-         env->n_call_nodes--;
-         eset_insert_all(env->call_nodes, callee_env->call_nodes);
-         env->n_call_nodes += callee_env->n_call_nodes;
-         env->n_nodes += callee_env->n_nodes;
-         callee_env->n_callers--;
-       }
+      did_inline = 1;
+      env->n_call_nodes--;
+      eset_insert_all(env->call_nodes, callee_env->call_nodes);
+      env->n_call_nodes += callee_env->n_call_nodes;
+      env->n_nodes += callee_env->n_nodes;
+      callee_env->n_callers--;
+    }
       } else {
         eset_insert(env->call_nodes, call);
       }
@@ -1329,8 +1357,9 @@ place_floats_early(ir_node *n, pdeq *worklist)
 
   /* Place floating nodes. */
   if (get_op_pinned(get_irn_op(n)) == floats) {
-    int depth = 0;
-    ir_node *b = new_Bad();   /* The block to place this node in */
+    int depth         = 0;
+    ir_node *b        = new_Bad();   /* The block to place this node in */
+    int bad_recursion = is_Bad(get_nodes_block(n));
 
     assert(get_irn_op(n) != op_Block);
 
@@ -1348,24 +1377,33 @@ place_floats_early(ir_node *n, pdeq *worklist)
     for (i = 0; i < irn_arity; i++) {
       ir_node *dep = get_irn_n(n, i);
       ir_node *dep_block;
-      if ((irn_not_visited(dep)) &&
-      (get_op_pinned(get_irn_op(dep)) == floats)) {
-       place_floats_early(dep, worklist);
+
+      if ((irn_not_visited(dep))
+     && (get_op_pinned(get_irn_op(dep)) == floats)) {
+    place_floats_early(dep, worklist);
       }
+
+      /*
+       * A node in the Bad block must stay in the bad block,
+       * so don't compute a new block for it.
+       */
+      if (bad_recursion)
+        continue;
+
       /* Because all loops contain at least one pinned node, now all
          our inputs are either pinned or place_early has already
          been finished on them.  We do not have any unfinished inputs!  */
       dep_block = get_nodes_Block(dep);
       if ((!is_Bad(dep_block)) &&
-         (get_Block_dom_depth(dep_block) > depth)) {
-       b = dep_block;
-       depth = get_Block_dom_depth(dep_block);
+      (get_Block_dom_depth(dep_block) > depth)) {
+    b = dep_block;
+    depth = get_Block_dom_depth(dep_block);
       }
       /* Avoid that the node is placed in the Start block */
       if ((depth == 1) && (get_Block_dom_depth(get_nodes_Block(n)) > 1)) {
-       b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
-       assert(b != get_irg_start_block(current_ir_graph));
-       depth = 2;
+    b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
+    assert(b != get_irg_start_block(current_ir_graph));
+    depth = 2;
       }
     }
     set_nodes_Block(n, b);
@@ -1384,7 +1422,7 @@ place_floats_early(ir_node *n, pdeq *worklist)
 
 /**
  * Floating nodes form subgraphs that begin at nodes as Const, Load,
- * Start, Call and end at pinned nodes as Store, Call.  Place_early
+ * Start, Call and that end at pinned nodes as Store, Call.  Place_early
  * places all floating nodes reachable from its argument through floating
  * nodes and adds all beginnings at pinned nodes to the worklist.
  */
@@ -1573,7 +1611,7 @@ void place_code(ir_graph *irg) {
   if (get_irg_dom_state(irg) != dom_consistent)
     compute_doms(irg);
 
-  if (get_irg_loopinfo_state(irg) != loopinfo_consistent) {
+  if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) {
     free_loop_information(irg);
     construct_backedges(irg);
   }
@@ -1620,7 +1658,7 @@ static void merge_blocks(ir_node *n, void *env) {
       /* GL @@@ : is this possible? if (get_opt_normalize()) -- added, all tests go through.
        A different order of optimizations might cause problems. */
       if (get_opt_normalize())
-       set_Block_cfgpred(n, i, skip_Tuple(get_Block_cfgpred(n, i)));
+    set_Block_cfgpred(n, i, skip_Tuple(get_Block_cfgpred(n, i)));
   } else if (get_opt_optimize() && (get_irn_mode(n) == mode_X)) {
     /* We will soon visit a block.  Optimize it before visiting! */
     ir_node *b = get_nodes_Block(n);
@@ -1636,7 +1674,6 @@ static void merge_blocks(ir_node *n, void *env) {
       b = new_node;
       new_node = equivalent_node(b);
     }
-    /* GL @@@ get_opt_normalize hinzugefuegt, 5.5.2003 */
     if (is_Bad(new_node) && get_opt_normalize()) exchange(n, new_Bad());
   }
 }
@@ -1654,7 +1691,7 @@ static void collect_nodes(ir_node *n, void *env) {
       /* Collect Phi nodes to compact ins along with block's ins. */
       set_irn_link(n, get_irn_link(b));
       set_irn_link(b, n);
-    } else if (get_irn_op(n) != op_Jmp) {  /* Check for non empty block. */
+    } else if ((get_irn_op(n) != op_Jmp) && !is_Bad(b)) {  /* Check for non empty block. */
       mark_Block_block_visited(b);
     }
   }
@@ -1691,24 +1728,24 @@ static int test_whether_dispensable(ir_node *b, int pos) {
       /* b's pred blocks and pred's pred blocks must be pairwise disjunct.
      Work preds < pos as if they were already removed. */
       for (i = 0; i < pos; i++) {
-       ir_node *b_pred = get_nodes_Block(get_Block_cfgpred(b, i));
-       if (get_Block_block_visited(b_pred) + 1
-           < get_irg_block_visited(current_ir_graph)) {
-         for (j = 0; j < get_Block_n_cfgpreds(b_pred); j++) {
-           ir_node *b_pred_pred = get_nodes_Block(get_Block_cfgpred(b_pred, j));
-           if (is_pred_of(b_pred_pred, pred)) dispensable = 0;
-         }
-       } else {
-         if (is_pred_of(b_pred, pred)) dispensable = 0;
-       }
+    ir_node *b_pred = get_nodes_Block(get_Block_cfgpred(b, i));
+    if (get_Block_block_visited(b_pred) + 1
+        < get_irg_block_visited(current_ir_graph)) {
+      for (j = 0; j < get_Block_n_cfgpreds(b_pred); j++) {
+        ir_node *b_pred_pred = get_nodes_Block(get_Block_cfgpred(b_pred, j));
+        if (is_pred_of(b_pred_pred, pred)) dispensable = 0;
+      }
+    } else {
+      if (is_pred_of(b_pred, pred)) dispensable = 0;
+    }
       }
       for (i = pos +1; i < get_Block_n_cfgpreds(b); i++) {
-       ir_node *b_pred = get_nodes_Block(get_Block_cfgpred(b, i));
-       if (is_pred_of(b_pred, pred)) dispensable = 0;
+    ir_node *b_pred = get_nodes_Block(get_Block_cfgpred(b, i));
+    if (is_pred_of(b_pred, pred)) dispensable = 0;
       }
       if (!dispensable) {
-       set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
-       n_preds = 1;
+    set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
+    n_preds = 1;
       } else {
         n_preds = get_Block_n_cfgpreds(pred);
       }
@@ -1753,35 +1790,35 @@ static void optimize_blocks(ir_node *b, void *env) {
     for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
       pred = get_nodes_Block(get_Block_cfgpred(b, i));
       if (is_Bad(get_Block_cfgpred(b, i))) {
-       /* Do nothing */
+    /* Do nothing */
       } else if (get_Block_block_visited(pred) +1
          < get_irg_block_visited(current_ir_graph)) {
-       /* It's an empty block and not yet visited. */
-       ir_node *phi_pred = get_Phi_pred(phi, i);
-       for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
-         if (get_nodes_Block(phi_pred) == pred) {
-           assert(get_irn_op(phi_pred) == op_Phi);  /* Block is empty!! */
-           in[n_preds] = get_Phi_pred(phi_pred, j);
-         } else {
-           in[n_preds] = phi_pred;
-         }
-         n_preds++;
-       }
-       /* The Phi_pred node is replaced now if it is a Phi.
-          In Schleifen kann offenbar der entfernte Phi Knoten legal verwendet werden.
-          Daher muss der Phiknoten durch den neuen ersetzt werden.
-          Weiter muss der alte Phiknoten entfernt werden (durch ersetzen oder
-          durch einen Bad) damit er aus den keep_alive verschwinden kann.
-          Man sollte also, falls keine Schleife vorliegt, exchange mit new_Bad
-          aufrufen.  */
-       if (get_nodes_Block(phi_pred) == pred) {
-         /* remove the Phi as it might be kept alive. Further there
-            might be other users. */
-         exchange(phi_pred, phi);  /* geht, ist aber doch semantisch falsch! Warum?? */
-       }
+    /* It's an empty block and not yet visited. */
+    ir_node *phi_pred = get_Phi_pred(phi, i);
+    for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
+      if (get_nodes_Block(phi_pred) == pred) {
+        assert(get_irn_op(phi_pred) == op_Phi);  /* Block is empty!! */
+        in[n_preds] = get_Phi_pred(phi_pred, j);
+      } else {
+        in[n_preds] = phi_pred;
+      }
+      n_preds++;
+    }
+    /* The Phi_pred node is replaced now if it is a Phi.
+       In Schleifen kann offenbar der entfernte Phi Knoten legal verwendet werden.
+       Daher muss der Phiknoten durch den neuen ersetzt werden.
+       Weiter muss der alte Phiknoten entfernt werden (durch ersetzen oder
+       durch einen Bad) damit er aus den keep_alive verschwinden kann.
+       Man sollte also, falls keine Schleife vorliegt, exchange mit new_Bad
+       aufrufen.  */
+    if (get_nodes_Block(phi_pred) == pred) {
+      /* remove the Phi as it might be kept alive. Further there
+         might be other users. */
+      exchange(phi_pred, phi);  /* geht, ist aber doch semantisch falsch! Warum?? */
+    }
       } else {
-       in[n_preds] = get_Phi_pred(phi, i);
-       n_preds ++;
+    in[n_preds] = get_Phi_pred(phi, i);
+    n_preds ++;
       }
     }
     /* Fix the node */
@@ -1797,52 +1834,52 @@ static void optimize_blocks(ir_node *b, void *env) {
     if (get_Block_block_visited(pred)+1 < get_irg_block_visited(current_ir_graph)) {
       phi = get_irn_link(pred);
       while (phi) {
-       if (get_irn_op(phi) == op_Phi) {
-         set_nodes_Block(phi, b);
-
-         n_preds = 0;
-         for (i = 0; i < k; i++) {
-           pred = get_nodes_Block(get_Block_cfgpred(b, i));
-           if (is_Bad(get_Block_cfgpred(b, i))) {
-             /* Do nothing */
-           } else if (get_Block_block_visited(pred) +1
-                  < get_irg_block_visited(current_ir_graph)) {
-             /* It's an empty block and not yet visited. */
-             for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
-           /* @@@ Hier brauche ich Schleifeninformation!!! Kontrollflusskante
-              muss Rueckwaertskante sein! (An allen vier in[n_preds] = phi
-              Anweisungen.) Trotzdem tuts bisher!! */
-           in[n_preds] = phi;
-           n_preds++;
-             }
-           } else {
-             in[n_preds] = phi;
-             n_preds++;
-           }
-         }
-         for (i = 0; i < get_Phi_n_preds(phi); i++) {
-           in[n_preds] = get_Phi_pred(phi, i);
-           n_preds++;
-         }
-         for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
-           pred = get_nodes_Block(get_Block_cfgpred(b, i));
-           if (is_Bad(get_Block_cfgpred(b, i))) {
-             /* Do nothing */
-           } else if (get_Block_block_visited(pred) +1
-                  < get_irg_block_visited(current_ir_graph)) {
-             /* It's an empty block and not yet visited. */
-             for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
-               in[n_preds] = phi;
-               n_preds++;
-             }
-           } else {
-             in[n_preds] = phi;
-             n_preds++;
-           }
-         }
-         set_irn_in(phi, n_preds, in);
-       }
-       phi = get_irn_link(phi);
+    if (get_irn_op(phi) == op_Phi) {
+      set_nodes_Block(phi, b);
+
+      n_preds = 0;
+      for (i = 0; i < k; i++) {
+        pred = get_nodes_Block(get_Block_cfgpred(b, i));
+        if (is_Bad(get_Block_cfgpred(b, i))) {
+          /* Do nothing */
+        } else if (get_Block_block_visited(pred) +1
+           < get_irg_block_visited(current_ir_graph)) {
+          /* It's an empty block and not yet visited. */
+          for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
+        /* @@@ Hier brauche ich Schleifeninformation!!! Kontrollflusskante
+           muss Rueckwaertskante sein! (An allen vier in[n_preds] = phi
+           Anweisungen.) Trotzdem tuts bisher!! */
+        in[n_preds] = phi;
+        n_preds++;
+          }
+        } else {
+          in[n_preds] = phi;
+          n_preds++;
+        }
+      }
+      for (i = 0; i < get_Phi_n_preds(phi); i++) {
+        in[n_preds] = get_Phi_pred(phi, i);
+        n_preds++;
+      }
+      for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
+        pred = get_nodes_Block(get_Block_cfgpred(b, i));
+        if (is_Bad(get_Block_cfgpred(b, i))) {
+          /* Do nothing */
+        } else if (get_Block_block_visited(pred) +1
+           < get_irg_block_visited(current_ir_graph)) {
+          /* It's an empty block and not yet visited. */
+          for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
+        in[n_preds] = phi;
+        n_preds++;
+          }
+        } else {
+          in[n_preds] = phi;
+          n_preds++;
+        }
+      }
+      set_irn_in(phi, n_preds, in);
+    }
+    phi = get_irn_link(phi);
       }
     }
   }
@@ -1859,8 +1896,8 @@ static void optimize_blocks(ir_node *b, void *env) {
       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++) {
-       in[n_preds] = get_Block_cfgpred(pred, j);
-       n_preds++;
+    in[n_preds] = get_Block_cfgpred(pred, j);
+    n_preds++;
       }
       /* Remove block as it might be kept alive. */
       exchange(pred, b/*new_Bad()*/);
@@ -1903,14 +1940,14 @@ void optimize_cf(ir_graph *irg) {
     ir_node *ka = get_End_keepalive(end, i);
     if (irn_not_visited(ka)) {
       if ((get_irn_op(ka) == op_Block) && Block_not_block_visited(ka)) {
-       set_irg_block_visited(current_ir_graph,  /* Don't walk all the way to Start. */
-                     get_irg_block_visited(current_ir_graph)-1);
-       irg_block_walk(ka, optimize_blocks, NULL, NULL);
-       mark_irn_visited(ka);
-       ARR_APP1 (ir_node *, in, ka);
+    set_irg_block_visited(current_ir_graph,  /* Don't walk all the way to Start. */
+              get_irg_block_visited(current_ir_graph)-1);
+    irg_block_walk(ka, optimize_blocks, NULL, NULL);
+    mark_irn_visited(ka);
+    ARR_APP1 (ir_node *, in, ka);
       } else if (get_irn_op(ka) == op_Phi) {
-       mark_irn_visited(ka);
-       ARR_APP1 (ir_node *, in, ka);
+    mark_irn_visited(ka);
+    ARR_APP1 (ir_node *, in, ka);
       }
     }
   }
@@ -1947,20 +1984,20 @@ static void walk_critical_cf_edges(ir_node *n, void *env) {
       pre = get_irn_n(n, i);
       /* Predecessor has multiple successors. Insert new flow edge */
       if ((NULL != pre) &&
-       (op_Proj == get_irn_op(pre)) &&
-       op_Raise != get_irn_op(skip_Proj(pre))) {
-
-       /* set predecessor array for new block */
-       in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 1);
-       /* set predecessor of new block */
-       in[0] = pre;
-       block = new_Block(1, in);
-       /* insert new jmp node to new block */
-       switch_block(block);
-       jmp = new_Jmp();
-       switch_block(n);
-       /* set successor of new block */
-       set_irn_n(n, i, jmp);
+    (op_Proj == get_irn_op(pre)) &&
+    op_Raise != get_irn_op(skip_Proj(pre))) {
+
+    /* set predecessor array for new block */
+    in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 1);
+    /* set predecessor of new block */
+    in[0] = pre;
+    block = new_Block(1, in);
+    /* insert new jmp node to new block */
+    switch_block(block);
+    jmp = new_Jmp();
+    switch_block(n);
+    /* set successor of new block */
+    set_irn_n(n, i, jmp);
 
       } /* predecessor has multiple successors */
     } /* for all predecessors */