local_optimize() now kills unrteachable code if dominance info is available.
[libfirm] / ir / ir / irgopt.c
index bfd2ae1..560d47e 100644 (file)
@@ -92,6 +92,7 @@ optimize_in_place_wrapper (ir_node *n, void *env) {
 static INLINE void do_local_optimize(ir_node *n) {
   /* Handle graph state */
   assert(get_irg_phase_state(current_ir_graph) != phase_building);
+
   if (get_opt_global_cse())
     set_irg_pinned(current_ir_graph, op_pin_state_floats);
   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
@@ -100,7 +101,6 @@ static INLINE void do_local_optimize(ir_node *n) {
     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(current_ir_graph->value_table);
   current_ir_graph->value_table = new_identities();
@@ -118,11 +118,23 @@ void local_optimize_node(ir_node *n) {
   current_ir_graph = rem;
 }
 
+/**
+ * Block-Walker: uses dominance depth to mark dead blocks.
+ */
+static void kill_dead_blocks(ir_node *block, void *env)
+{
+  if (get_Block_dom_depth(block) < 0)
+    set_Block_dead(block);
+}
+
 void
 local_optimize_graph (ir_graph *irg) {
   ir_graph *rem = current_ir_graph;
   current_ir_graph = irg;
 
+  if (get_irg_dom_state(current_ir_graph) == dom_consistent)
+    irg_block_walk_graph(irg, NULL, kill_dead_blocks, NULL);
+
   do_local_optimize(irg->end);
 
   current_ir_graph = rem;
@@ -144,11 +156,10 @@ set_new_node (ir_node *old, ir_node *new)
 }
 
 /**
- * Get this new node, before the old node is forgotton.
+ * Get this new node, before the old node is forgotten.
  */
 static INLINE ir_node *
-get_new_node (ir_node * n)
-{
+get_new_node (ir_node * n) {
   return n->link;
 }
 
@@ -199,18 +210,24 @@ static INLINE void new_backedge_info(ir_node *n) {
   }
 }
 
-/*
- * Copies a node to the current_ir_graph. The Ins of the new node point to
- * the predecessors on the graph of the old node.  For block/phi nodes not all
- * predecessors might be copied.
+/**
+ * Copies the node to the new obstack. The Ins of the new node point to
+ * the predecessors on the old obstack.  For block/phi nodes not all
+ * predecessors might be copied.  n->link points to the new node.
  * For Phi and Block nodes the function allocates in-arrays with an arity
  * only for useful predecessors.  The arity is determined by counting
  * the non-bad predecessors of the block.
+ *
+ * @param n    The node to be copied
+ * @param env  if non-NULL, the node number attribute will be copied to the new node
+ *
+ * Note: Also used for loop unrolling.
  */
-ir_node *copy_irn(ir_node *n, int copy_node_nr) {
+static void copy_node(ir_node *n, void *env) {
   ir_node *nn, *block;
   int new_arity;
   ir_op *op = get_irn_op(n);
+  int copy_node_nr = env != NULL;
 
   /* 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
@@ -219,7 +236,7 @@ ir_node *copy_irn(ir_node *n, int copy_node_nr) {
 
   if (op == op_Bad) {
     /* node copied already */
-    return NULL;
+    return;
   } else if (op == op_Block) {
     block = NULL;
     new_arity = compute_new_arity(n);
@@ -252,30 +269,9 @@ ir_node *copy_irn(ir_node *n, int copy_node_nr) {
   }
 #endif
 
-  return nn;
+  set_new_node(n, nn);
 }
 
-/**
- * Copies the node to the new obstack. The Ins of the new node point to
- * the predecessors on the old obstack.  For block/phi nodes not all
- * predecessors might be copied.  n->link points to the new node.
- * For Phi and Block nodes the function allocates in-arrays with an arity
- * only for useful predecessors.  The arity is determined by counting
- * the non-bad predecessors of the block.
- *
- * @param n    The node to be copied
- * @param env  if non-NULL, the node number attribute will be copied to the new node
- *
- * Note: Also used for loop unrolling.
- */
-static void firm_copy_node (ir_node *n, void *env) {
-  ir_node *nn = copy_irn(n, env != NULL);
-
-  if (nn)
-    set_new_node(n, nn);
-}
-
-
 /**
  * Copies new predecessors of old node to new node remembered in link.
  * Spare the Bad predecessors of Phi and Block nodes.
@@ -399,7 +395,7 @@ copy_graph (int copy_node_nr) {
   set_new_node(om, nm);
 
   /* copy the live nodes */
-  irg_walk(get_nodes_block(oe), firm_copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
+  irg_walk(get_nodes_block(oe), copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
   /* copy_preds for the end node ... */
   set_nodes_block(ne, get_new_node(get_nodes_block(oe)));
 
@@ -413,7 +409,7 @@ copy_graph (int copy_node_nr) {
         (get_irn_visited(ka) < get_irg_visited(current_ir_graph))) {
       /* We must keep the block alive and copy everything reachable */
       set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
-      irg_walk(ka, firm_copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
+      irg_walk(ka, copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
       add_End_keepalive(ne, get_new_node(ka));
     }
   }
@@ -426,7 +422,7 @@ copy_graph (int copy_node_nr) {
       if (get_irn_visited(ka) < get_irg_visited(current_ir_graph)) {
         /* We didn't copy the Phi yet.  */
         set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
-        irg_walk(ka, firm_copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
+        irg_walk(ka, copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
       }
       add_End_keepalive(ne, get_new_node(ka));
     }
@@ -471,19 +467,19 @@ copy_graph_env (int copy_node_nr) {
   free_End(old_end);
   set_irg_end_block  (current_ir_graph, get_new_node(get_irg_end_block(current_ir_graph)));
   if (get_irn_link(get_irg_frame(current_ir_graph)) == NULL) {
-    firm_copy_node (get_irg_frame(current_ir_graph), INT_TO_PTR(copy_node_nr));
+    copy_node (get_irg_frame(current_ir_graph), INT_TO_PTR(copy_node_nr));
     copy_preds(get_irg_frame(current_ir_graph), NULL);
   }
   if (get_irn_link(get_irg_globals(current_ir_graph)) == NULL) {
-    firm_copy_node (get_irg_globals(current_ir_graph), INT_TO_PTR(copy_node_nr));
+    copy_node (get_irg_globals(current_ir_graph), INT_TO_PTR(copy_node_nr));
     copy_preds(get_irg_globals(current_ir_graph), NULL);
   }
   if (get_irn_link(get_irg_initial_mem(current_ir_graph)) == NULL) {
-    firm_copy_node (get_irg_initial_mem(current_ir_graph), INT_TO_PTR(copy_node_nr));
+    copy_node (get_irg_initial_mem(current_ir_graph), INT_TO_PTR(copy_node_nr));
     copy_preds(get_irg_initial_mem(current_ir_graph), NULL);
   }
   if (get_irn_link(get_irg_args(current_ir_graph)) == NULL) {
-    firm_copy_node (get_irg_args(current_ir_graph), INT_TO_PTR(copy_node_nr));
+    copy_node (get_irg_args(current_ir_graph), INT_TO_PTR(copy_node_nr));
     copy_preds(get_irg_args(current_ir_graph), NULL);
   }
   set_irg_start      (current_ir_graph, get_new_node(get_irg_start(current_ir_graph)));
@@ -496,13 +492,13 @@ copy_graph_env (int copy_node_nr) {
   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) {
-    firm_copy_node(get_irg_bad(current_ir_graph), INT_TO_PTR(copy_node_nr));
+    copy_node(get_irg_bad(current_ir_graph), INT_TO_PTR(copy_node_nr));
     copy_preds(get_irg_bad(current_ir_graph), NULL);
   }
   set_irg_bad(current_ir_graph, get_new_node(get_irg_bad(current_ir_graph)));
 
   if (get_irn_link(get_irg_no_mem(current_ir_graph)) == NULL) {
-    firm_copy_node(get_irg_no_mem(current_ir_graph), INT_TO_PTR(copy_node_nr));
+    copy_node(get_irg_no_mem(current_ir_graph), INT_TO_PTR(copy_node_nr));
     copy_preds(get_irg_no_mem(current_ir_graph), NULL);
   }
   set_irg_no_mem(current_ir_graph, get_new_node(get_irg_no_mem(current_ir_graph)));
@@ -598,19 +594,19 @@ static void relink_bad_block_predecessors(ir_node *n, void *env) {
     /* arity changing: set new predecessors without bad nodes */
     if (new_irn_arity < old_irn_arity) {
       /* Get new predecessor array. We do not resize the array, as we must
-        keep the old one to update Phis. */
+         keep the old one to update Phis. */
       new_in = NEW_ARR_D (ir_node *, current_ir_graph->obst, (new_irn_arity+1));
 
       /* set new predecessors in array */
       new_in[0] = NULL;
       new_irn_n = 1;
       for (i = 0; i < old_irn_arity; i++) {
-       irn = get_irn_n(n, i);
-       if (!is_Bad(irn)) {
-         new_in[new_irn_n] = irn;
-         is_backedge(n, i) ? set_backedge(n, new_irn_n-1) : set_not_backedge(n, new_irn_n-1);
-         new_irn_n++;
-       }
+        irn = get_irn_n(n, i);
+        if (!is_Bad(irn)) {
+               new_in[new_irn_n] = irn;
+               is_backedge(n, i) ? set_backedge(n, new_irn_n-1) : set_not_backedge(n, new_irn_n-1);
+               new_irn_n++;
+        }
       }
       //ARR_SETLEN(int, n->attr.block.backedge, new_irn_arity);
       ARR_SHRINKLEN(n->attr.block.backedge, new_irn_arity);
@@ -650,14 +646,14 @@ static void relink_bad_predecessors(ir_node *n, void *env) {
     /* Relink Phi predecessors if count of predecessors changed */
     if (old_irn_arity != ARR_LEN(get_irn_in(block))) {
       /* set new predecessors in array
-        n->in[0] remains the same block */
+         n->in[0] remains the same block */
       new_irn_arity = 1;
       for(i = 1; i < old_irn_arity; i++)
-       if (!is_Bad((ir_node *)old_in[i])) {
-         n->in[new_irn_arity] = n->in[i];
-         is_backedge(n, i) ? set_backedge(n, new_irn_arity) : set_not_backedge(n, new_irn_arity);
-         new_irn_arity++;
-       }
+        if (!is_Bad((ir_node *)old_in[i])) {
+               n->in[new_irn_arity] = n->in[i];
+               is_backedge(n, i) ? set_backedge(n, new_irn_arity) : set_not_backedge(n, new_irn_arity);
+               new_irn_arity++;
+        }
 
       ARR_SETLEN(ir_node *, n->in, new_irn_arity);
       ARR_SETLEN(int, n->attr.phi_backedge, new_irn_arity);
@@ -681,14 +677,14 @@ void remove_bad_predecessors(ir_graph *irg) {
 
 
 /*--------------------------------------------------------------------*/
-/*  Funcionality for inlining                                         */
+/*  Functionality for inlining                                         */
 /*--------------------------------------------------------------------*/
 
 /**
  * Copy node for inlineing.  Updates attributes that change when
  * inlineing but not for dead node elimination.
  *
- * Copies the node by calling firm_copy_node and then updates the entity if
+ * Copies the node by calling copy_node() and then updates the entity if
  * it's a local one.  env must be a pointer of the frame type of the
  * inlined procedure. The new entities must be in the link field of
  * the entities.
@@ -698,7 +694,7 @@ copy_node_inline (ir_node *n, void *env) {
   ir_node *new;
   type *frame_tp = (type *)env;
 
-  firm_copy_node(n, NULL);
+  copy_node(n, NULL);
   if (get_irn_op(n) == op_Sel) {
     new = get_new_node (n);
     assert(get_irn_op(new) == op_Sel);
@@ -937,7 +933,7 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
     add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
 
   /* The new end node will die.  We need not free as the in array is on the obstack:
-     firm_copy_node only generated 'D' arrays. */
+     copy_node() only generated 'D' arrays. */
 
   /* -- Replace Return nodes by Jump nodes. -- */
   n_ret = 0;
@@ -1234,7 +1230,7 @@ typedef struct {
 } inline_irg_env;
 
 /**
- * Allocate a new nvironment for inlining.
+ * Allocate a new environment for inlining.
  */
 static inline_irg_env *new_inline_irg_env(void) {
   inline_irg_env *env    = xmalloc(sizeof(*env));
@@ -1438,6 +1434,8 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
 
 /**
  * Returns non-zero, is a block is not reachable from Start.
+ *
+ * @param block  the block to test
  */
 static int
 is_Block_unreachable(ir_node *block) {
@@ -1450,21 +1448,31 @@ is_Block_unreachable(ir_node *block) {
  *
  * We have to avoid calls to get_nodes_block() here
  * because the graph is floating.
+ *
+ * move_out_of_loops() expects that place_floats_early() have placed
+ * all "living" nodes into a living block. That's why we must
+ * move nodes in dead block with "live" successors into a valid
+ * block.
+ * We move them just into the same block as it's successor (or
+ * in case of a Phi into the effective use block). For Phi successors,
+ * this may still be a dead block, but then there is no real use, as
+ * the control flow will be dead later.
  */
 static void
 place_floats_early(ir_node *n, pdeq *worklist)
 {
-  int i, start, irn_arity;
+  int i, irn_arity;
 
   /* we must not run into an infinite loop */
-  assert (irn_not_visited(n));
+  assert(irn_not_visited(n));
   mark_irn_visited(n);
 
   /* Place floating nodes. */
   if (get_irn_pinned(n) == op_pin_state_floats) {
-    int depth         = 0;
-    ir_node *b        = NULL;   /* The block to place this node in */
-    int bad_recursion = is_Block_unreachable(get_irn_n(n, -1));
+    ir_node *curr_block = get_irn_n(n, -1);
+    int in_dead_block   = is_Block_unreachable(curr_block);
+    int depth           = 0;
+    ir_node *b          = NULL;   /* The block to place this node in */
 
     assert(get_irn_op(n) != op_Block);
 
@@ -1480,29 +1488,43 @@ place_floats_early(ir_node *n, pdeq *worklist)
     /* find the block for this node. */
     irn_arity = get_irn_arity(n);
     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_irn_pinned(dep) == op_pin_state_floats)) {
-        place_floats_early(dep, worklist);
+      ir_node *pred = get_irn_n(n, i);
+      ir_node *pred_block;
+
+      if ((irn_not_visited(pred))
+         && (get_irn_pinned(pred) == op_pin_state_floats)) {
+
+        /*
+         * If the current node is NOT in a dead block, but one of its
+         * predecessors is, we must move the predecessor to a live block.
+         * Such thing can happen, if global CSE chose a node from a dead block.
+         * We move it simple to our block.
+         * Note that neither Phi nor End nodes are floating, so we don't
+         * need to handle them here.
+         */
+        if (! in_dead_block) {
+          if (get_irn_pinned(pred) == op_pin_state_floats &&
+              is_Block_unreachable(get_irn_n(pred, -1)))
+            set_nodes_block(pred, curr_block);
+        }
+        place_floats_early(pred, 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)
+      if (in_dead_block)
         continue;
 
       /* Because all loops contain at least one op_pin_state_pinned node, now all
-         our inputs are either op_pin_state_pinned or place_early has already
+         our inputs are either op_pin_state_pinned or place_early() has already
          been finished on them.  We do not have any unfinished inputs!  */
-      dep_block = get_irn_n(dep, -1);
-      if ((!is_Block_dead(dep_block)) &&
-          (get_Block_dom_depth(dep_block) > depth)) {
-        b = dep_block;
-        depth = get_Block_dom_depth(dep_block);
+      pred_block = get_irn_n(pred, -1);
+      if ((!is_Block_dead(pred_block)) &&
+          (get_Block_dom_depth(pred_block) > depth)) {
+        b = pred_block;
+        depth = get_Block_dom_depth(pred_block);
       }
       /* Avoid that the node is placed in the Start block */
       if ((depth == 1) && (get_Block_dom_depth(get_irn_n(n, -1)) > 1)) {
@@ -1515,13 +1537,83 @@ place_floats_early(ir_node *n, pdeq *worklist)
       set_nodes_block(n, b);
   }
 
-  /* Add predecessors of non floating nodes on worklist. */
-  start = (get_irn_op(n) == op_Block) ? 0 : -1;
+  /*
+   * Add predecessors of non floating nodes and non-floating predecessors
+   * of floating nodes to worklist and fix their blocks if the are in dead block.
+   */
   irn_arity = get_irn_arity(n);
-  for (i = start; i < irn_arity; i++) {
-    ir_node *pred = get_irn_n(n, i);
-    if (irn_not_visited(pred)) {
-      pdeq_putr (worklist, pred);
+
+  if (get_irn_op(n) == op_End) {
+    /*
+     * Simplest case: End node. Predecessors are keep-alives,
+     * no need to move out of dead block.
+     */
+    for (i = -1; i < irn_arity; ++i) {
+      ir_node *pred = get_irn_n(n, i);
+      if (irn_not_visited(pred))
+        pdeq_putr(worklist, pred);
+    }
+  }
+  else if (is_Block(n)) {
+    /*
+     * Blocks: Predecessors are control flow, no need to move
+     * them out of dead block.
+     */
+    for (i = irn_arity - 1; i >= 0; --i) {
+      ir_node *pred = get_irn_n(n, i);
+      if (irn_not_visited(pred))
+        pdeq_putr(worklist, pred);
+    }
+  }
+  else if (is_Phi(n)) {
+    ir_node *pred;
+    ir_node *curr_block = get_irn_n(n, -1);
+    int in_dead_block   = is_Block_unreachable(curr_block);
+
+    /*
+     * Phi nodes: move nodes from dead blocks into the effective use
+     * of the Phi-input if the Phi is not in a bad block.
+     */
+    pred = get_irn_n(n, -1);
+    if (irn_not_visited(pred))
+      pdeq_putr(worklist, pred);
+
+    for (i = irn_arity - 1; i >= 0; --i) {
+      ir_node *pred = get_irn_n(n, i);
+
+      if (irn_not_visited(pred)) {
+        if (! in_dead_block &&
+            get_irn_pinned(pred) == op_pin_state_floats &&
+            is_Block_unreachable(get_irn_n(pred, -1))) {
+          set_nodes_block(pred, get_Block_cfgpred_block(curr_block, i));
+        }
+        pdeq_putr(worklist, pred);
+      }
+    }
+  }
+  else {
+    ir_node *pred;
+    ir_node *curr_block = get_irn_n(n, -1);
+    int in_dead_block   = is_Block_unreachable(curr_block);
+
+    /*
+     * All other nodes: move nodes from dead blocks into the same block.
+     */
+    pred = get_irn_n(n, -1);
+    if (irn_not_visited(pred))
+      pdeq_putr(worklist, pred);
+
+    for (i = irn_arity - 1; i >= 0; --i) {
+      ir_node *pred = get_irn_n(n, i);
+
+      if (irn_not_visited(pred)) {
+        if (! in_dead_block &&
+            get_irn_pinned(pred) == op_pin_state_floats &&
+            is_Block_unreachable(get_irn_n(pred, -1))) {
+          set_nodes_block(pred, curr_block);
+        }
+        pdeq_putr(worklist, pred);
+      }
     }
   }
 }
@@ -1540,9 +1632,10 @@ static INLINE void place_early(pdeq *worklist) {
   place_floats_early(get_irg_end(current_ir_graph), worklist);
 
   /* Work the content of the worklist. */
-  while (!pdeq_empty (worklist)) {
-    ir_node *n = pdeq_getl (worklist);
-    if (irn_not_visited(n)) place_floats_early(n, worklist);
+  while (!pdeq_empty(worklist)) {
+    ir_node *n = pdeq_getl(worklist);
+    if (irn_not_visited(n))
+      place_floats_early(n, worklist);
   }
 
   set_irg_outs_inconsistent(current_ir_graph);
@@ -1582,7 +1675,7 @@ static ir_node *calc_dca(ir_node *dca, ir_node *block)
  * A data flow edge points from producer to consumer.
  */
 static ir_node *
-consumer_dom_dca (ir_node *dca, ir_node *consumer, ir_node *producer)
+consumer_dom_dca(ir_node *dca, ir_node *consumer, ir_node *producer)
 {
   ir_node *block = NULL;
 
@@ -1606,8 +1699,8 @@ consumer_dom_dca (ir_node *dca, ir_node *consumer, ir_node *producer)
 
     if (! block)
       block = get_irn_n(producer, -1);
-
-  else {
+  }
+  else {
     assert(is_no_Block(consumer));
     block = get_nodes_block(consumer);
   }
@@ -1672,9 +1765,9 @@ static void
 place_floats_late(ir_node *n, pdeq *worklist)
 {
   int i;
-  ir_node *early;
+  ir_node *early_blk;
 
-  assert (irn_not_visited(n)); /* no multiple placement */
+  assert(irn_not_visited(n)); /* no multiple placement */
 
   mark_irn_visited(n);
 
@@ -1682,9 +1775,9 @@ place_floats_late(ir_node *n, pdeq *worklist)
   if ((get_irn_op(n) != op_Block) &&
       (!is_cfop(n)) &&
       (get_irn_mode(n) != mode_X)) {
-    /* Remember the early placement of this block to move it
-       out of loop no further than the early placement. */
-    early = get_irn_n(n, -1);
+    /* Remember the early_blk placement of this block to move it
+       out of loop no further than the early_blk placement. */
+    early_blk = get_irn_n(n, -1);
 
     /*
      * BEWARE: Here we also get code, that is live, but
@@ -1706,38 +1799,41 @@ place_floats_late(ir_node *n, pdeq *worklist)
         place_floats_late(succ, worklist);
     }
 
-    /* We have to determine the final block of this node... except for
-       constants. */
-    if ((get_irn_pinned(n) == op_pin_state_floats) &&
-        (get_irn_op(n) != op_Const) &&
-        (get_irn_op(n) != op_SymConst)) {
-      ir_node *dca = NULL;  /* deepest common ancestor in the
-                   dominator tree of all nodes'
-                   blocks depending on us; our final
-                   placement has to dominate DCA. */
-      for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
-        ir_node *out = get_irn_out(n, i);
-        ir_node *outbl;
-
-        if (get_irn_op(out) == op_End) {
-          /*
-           * This consumer is the End node, a keep alive edge.
-           * This is not a real consumer, so we ignore it
-           */
-          continue;
-        }
+    if (! is_Block_dead(early_blk)) {
+      /* do only move things that where not dead */
+
+      /* We have to determine the final block of this node... except for
+         constants. */
+      if ((get_irn_pinned(n) == op_pin_state_floats) &&
+          (get_irn_op(n) != op_Const) &&
+          (get_irn_op(n) != op_SymConst)) {
+        ir_node *dca = NULL;  /* deepest common ancestor in the
+                     dominator tree of all nodes'
+                     blocks depending on us; our final
+                     placement has to dominate DCA. */
+        for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
+          ir_node *succ = get_irn_out(n, i);
+          ir_node *succ_blk;
+
+          if (get_irn_op(succ) == op_End) {
+            /*
+             * This consumer is the End node, a keep alive edge.
+             * This is not a real consumer, so we ignore it
+             */
+            continue;
+          }
 
-        /* ignore if out is in dead code */
-        outbl = get_irn_n(out, -1);
-        if (is_Block_unreachable(outbl))
-          continue;
-        dca = consumer_dom_dca(dca, out, n);
-      }
-      if (dca) {
-        set_nodes_block(n, dca);
-        move_out_of_loops (n, early);
+          /* ignore if succ is in dead code */
+          succ_blk = get_irn_n(succ, -1);
+          if (is_Block_unreachable(succ_blk))
+            continue;
+          dca = consumer_dom_dca(dca, succ, n);
+        }
+        if (dca) {
+          set_nodes_block(n, dca);
+          move_out_of_loops(n, early_blk);
+        }
       }
-      /* else all outs are in dead code */
     }
   }
 
@@ -1746,7 +1842,7 @@ place_floats_late(ir_node *n, pdeq *worklist)
   for (i = 0; i < get_irn_n_outs(n); i++) {
     ir_node *succ = get_irn_out(n, i);
     if (irn_not_visited(get_irn_out(n, i))) {
-      pdeq_putr (worklist, succ);
+      pdeq_putr(worklist, succ);
     }
   }
 }
@@ -1759,9 +1855,10 @@ static INLINE void place_late(pdeq *worklist) {
   place_floats_late(get_irg_start_block(current_ir_graph), worklist);
 
   /* And now empty the worklist again... */
-  while (!pdeq_empty (worklist)) {
-    ir_node *n = pdeq_getl (worklist);
-    if (irn_not_visited(n)) place_floats_late(n, worklist);
+  while (!pdeq_empty(worklist)) {
+    ir_node *n = pdeq_getl(worklist);
+    if (irn_not_visited(n))
+      place_floats_late(n, worklist);
   }
 }
 
@@ -1788,8 +1885,9 @@ void place_code(ir_graph *irg) {
   worklist = new_pdeq();
   place_early(worklist);
 
-  /* place_early invalidates the outs, place_late needs them. */
+  /* place_early() invalidates the outs, place_late needs them. */
   compute_irg_outs(irg);
+
   /* Now move the nodes down in the dominator tree. This reduces the
      unnecessary executions of the node. */
   place_late(worklist);