Removed static worklist, fised some typos, added more doxygen comments
[libfirm] / ir / ir / irgopt.c
index 15cb664..40d5084 100644 (file)
@@ -412,6 +412,7 @@ 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_outs(current_ir_graph);
 
   /* @@@ so far we loose loops when copying */
@@ -571,8 +572,8 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
   ir_node **res_pred;
   ir_node **cf_pred;
   ir_node *ret, *phi;
-  ir_node *cf_op = NULL, *bl;
   int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity;
+  int exc_handling; ir_node *proj;
   type *called_frame;
 
   if (!get_optimize() || !get_opt_inline()) return;
@@ -600,6 +601,31 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
     return;
   }
 
+  /* -- 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. -- */
+  exc_handling = 2;
+  for (proj = (ir_node *)get_irn_link(call); proj; proj = (ir_node *)get_irn_link(proj)) {
+    assert(get_irn_op(proj) == op_Proj);
+    if (get_Proj_proj(proj) == pn_Call_M_except) { exc_handling = 0; break;}
+    if (get_Proj_proj(proj) == pn_Call_X_except) { exc_handling = 1; }
+  }
+
+  {
+    ir_node *proj, *Mproj = NULL, *Xproj = NULL;
+    for (proj = (ir_node *)get_irn_link(call); proj; proj = (ir_node *)get_irn_link(proj)) {
+      assert(get_irn_op(proj) == op_Proj);
+      if (get_Proj_proj(proj) == pn_Call_X_except) Xproj = proj;
+      if (get_Proj_proj(proj) == pn_Call_M_except) Mproj = proj;
+    }
+    if      (Mproj) { assert(Xproj); exc_handling = 0; }
+    else if (Xproj) {                exc_handling = 1; }
+    else            {                exc_handling = 2; }
+  }
+
+
   /* --
       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
@@ -673,12 +699,15 @@ void 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.
   */
 
   /* -- Precompute some values -- */
@@ -688,7 +717,7 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
   n_res = get_method_n_ress(get_Call_type(call));
 
   res_pred = (ir_node **) malloc (n_res * sizeof (ir_node *));
-  cf_pred = (ir_node **) malloc (arity * sizeof (ir_node *));
+  cf_pred =  (ir_node **) malloc (arity * sizeof (ir_node *));
 
   set_irg_current_block(current_ir_graph, post_bl); /* just to make sure */
 
@@ -700,8 +729,7 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
   /* The new end node will die.  We need not free as the in array is on the obstack:
      copy_node only generated 'D' arrays. */
 
-/* --
-      Return nodes by Jump nodes. -- */
+  /* -- Replace Return nodes by Jump nodes. -- */
   n_ret = 0;
   for (i = 0; i < arity; i++) {
     ir_node *ret;
@@ -713,8 +741,8 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
   }
   set_irn_in(post_bl, n_ret, cf_pred);
 
-/* --
-      turned into a tuple.  -- */
+  /* -- Build a Tuple for all results of the method.
+     Add Phi node if there was more than one Return.  -- */
   turn_into_tuple(post_call, 4);
   /* First the Memory-Phi */
   n_ret = 0;
@@ -755,48 +783,83 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
   } else {
     set_Tuple_pred(call, 2, new_Bad());
   }
-  /* Finally the exception control flow.  We need to add a Phi node to
+  /* Finally the exception control flow.
+     We have two (three) possible situations:
+     First if the Call branches to an exception handler: We need to add a Phi node to
      collect the memory containing the exception objects.  Further we need
      to add another block to get a correct representation of this Phi.  To
      this block we add a Jmp that resolves into the X output of the Call
-     when the Call is turned into a tuple. */
-  n_exc = 0;
-  for (i = 0; i < arity; i++) {
-    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++;
-    }
-  }
-  if (n_exc > 0) {
-    new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
-    set_Tuple_pred(call, 1, new_Jmp());
-    /* The Phi for the memories with the exception objects */
+     when the Call is turned into a tuple.
+     Second the Call branches to End, the exception is not handled.  Just
+     add all inlined exception branches to the End node.
+     Third: there is no Exception edge at all. Handle as case two. */
+  if (exc_handler == 0) {
     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);
+      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++;
-      } else if (is_fragile_op(ret)) {
+      }
+    }
+    if (n_exc > 0) {
+      new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
+      set_Tuple_pred(call, 1, new_Jmp());
+      /* 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++;
+         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, 3, new_Phi(n_exc, cf_pred, mode_M));
+    } else {
+      set_Tuple_pred(call, 1, new_Bad());
+      set_Tuple_pred(call, 3, new_Bad());
     }
-    set_Tuple_pred(call, 3, new_Phi(n_exc, cf_pred, mode_M));
   } else {
+    ir_node *main_end_bl;
+    int main_end_bl_arity;
+    ir_node **end_preds;
+
+    /* assert(exc_handler == 1 || no exceptions. ) */
+    n_exc = 0;
+    for (i = 0; i < arity; i++) {
+      ir_node *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++;
+      }
+    }
+    main_end_bl = get_irg_end_block(current_ir_graph);
+    main_end_bl_arity = get_irn_arity(main_end_bl);
+    end_preds =  (ir_node **) malloc ((n_exc + main_end_bl_arity) * sizeof (ir_node *));
+
+    for (i = 0; i < main_end_bl_arity; ++i)
+      end_preds[i] = get_irn_n(main_end_bl, i);
+    for (i = 0; i < n_exc; ++i)
+      end_preds[main_end_bl_arity + i] = cf_pred[i];
+    set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
     set_Tuple_pred(call, 1, new_Bad());
     set_Tuple_pred(call, 3, new_Bad());
+    free(end_preds);
   }
   free(res_pred);
   free(cf_pred);
 
+#if 0  /* old. now better, correcter, faster implementation. */
   if (n_exc > 0) {
     /* -- If the exception control flow from the inlined Call directly
        branched to the end block we now have the following control
@@ -804,7 +867,9 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
        remove the Jmp along with it's empty block and add Jmp's
        predecessors as predecessors of this end block.  No problem if
        there is no exception, because then branches Bad to End which
-       is fine. -- */
+       is fine. --
+       @@@ can't we know this beforehand: by getting the Proj(1) from
+       the Call link list and checking whether it goes to Proj. */
     /* find the problematic predecessor of the end block. */
     end_bl = get_irg_end_block(current_ir_graph);
     for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
@@ -837,6 +902,7 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
     }
   }
+#endif
 
   /* --  Turn cse back on. -- */
   set_optimize(rem_opt);
@@ -873,13 +939,13 @@ static ir_graph *get_call_called_irg(ir_node *call) {
 
 static void collect_calls(ir_node *call, void *env) {
 
-  if (get_irn_op(call) != op_Call) return;
-
   ir_node **calls = (ir_node **)env;
   ir_node *addr;
   tarval *tv;
   ir_graph *called_irg;
 
+  if (get_irn_op(call) != op_Call) return;
+
   addr = get_Call_ptr(call);
   if (get_irn_op(addr) == op_Const) {
     /* Check whether the constant is the pointer to a compiled entity. */
@@ -887,9 +953,9 @@ static void collect_calls(ir_node *call, void *env) {
     if (tarval_to_entity(tv)) {
       called_irg = get_entity_irg(tarval_to_entity(tv));
       if (called_irg && pos < MAX_INLINE) {
-       /* The Call node calls a locally defined method.  Remember to inline. */
-       calls[pos] = call;
-       pos++;
+        /* The Call node calls a locally defined method.  Remember to inline. */
+        calls[pos] = call;
+        pos++;
       }
     }
   }
@@ -911,6 +977,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);
 
   /* Find Call nodes to inline.
      (We can not inline during a walk of the graph, as inlineing the same
@@ -929,7 +996,7 @@ void inline_small_irgs(ir_graph *irg, int size) {
       tv = get_Const_tarval(get_Call_ptr(calls[i]));
       callee = get_entity_irg(tarval_to_entity(tv));
       if ((_obstack_memory_used(callee->obst) - obstack_room(callee->obst)) < size) {
-       inline_method(calls[i], callee);
+        inline_method(calls[i], callee);
       }
     }
   }
@@ -937,14 +1004,17 @@ void inline_small_irgs(ir_graph *irg, int size) {
   current_ir_graph = rem;
 }
 
+/**
+ * Environment for inlining irgs.
+ */
 typedef struct {
-  int n_nodes;       /* Nodes in graph except Id, Tuple, Proj, Start, End */
-  int n_nodes_orig;  /* for statistics */
-  eset *call_nodes;  /* All call nodes in this graph */
+  int n_nodes;       /**< Nodes in graph except Id, Tuple, Proj, Start, End */
+  int n_nodes_orig;  /**< for statistics */
+  eset *call_nodes;  /**< All call nodes in this graph */
   int n_call_nodes;
-  int n_call_nodes_orig; /* for statistics */
-  int n_callers;   /* Number of known graphs that call this graphs. */
-  int n_callers_orig; /* for statistics */
+  int n_call_nodes_orig; /**< for statistics */
+  int n_callers;   /**< Number of known graphs that call this graphs. */
+  int n_callers_orig; /**< for statistics */
 } inline_irg_env;
 
 static inline_irg_env *new_inline_irg_env(void) {
@@ -967,6 +1037,7 @@ static void free_inline_irg_env(inline_irg_env *env) {
 static void collect_calls2(ir_node *call, void *env) {
   inline_irg_env *x = (inline_irg_env *)env;
   ir_op *op = get_irn_op(call);
+  ir_graph *callee;
 
   /* count nodes in irg */
   if (op != op_Proj && op != op_Tuple && op != op_Sync) {
@@ -982,7 +1053,7 @@ static void collect_calls2(ir_node *call, void *env) {
   x->n_call_nodes_orig++;
 
   /* count all static callers */
-  ir_graph *callee = get_call_called_irg(call);
+  callee = get_call_called_irg(call);
   if (callee) {
     ((inline_irg_env *)get_irg_link(callee))->n_callers++;
     ((inline_irg_env *)get_irg_link(callee))->n_callers_orig++;
@@ -1012,14 +1083,15 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
 
   if (!(get_optimize() && get_opt_inline())) return;
 
-  /* extend all irgs by a temporary datastructure for inlineing. */
+  /* extend all irgs by a temporary data structure for inlineing. */
   for (i = 0; i < n_irgs; ++i)
     set_irg_link(get_irp_irg(i), new_inline_irg_env());
 
-  /* Precompute information in temporary datastructure. */
+  /* Precompute information in temporary data structure. */
   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);
 
     irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2,
             get_irg_link(current_ir_graph));
@@ -1041,30 +1113,32 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
       env = (inline_irg_env *)get_irg_link(current_ir_graph);
 
       /* we can not walk and change a set, nor remove from it.
-        So recompute.*/
+      So recompute.*/
       walkset = env->call_nodes;
       env->call_nodes = eset_create();
       for (call = eset_first(walkset); call; call = eset_next(walkset)) {
-       ir_graph *callee = get_call_called_irg(call);
-       if (env->n_nodes > maxsize) break;
-       if (callee && is_leave(callee) && is_smaller(callee, leavesize)) {
-         if (!phiproj_computed) {
-           phiproj_computed = 1;
-           collect_phiprojs(current_ir_graph);
-         }
-         inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
-         // printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)),
-         //     get_entity_name(get_irg_entity(callee)));
-         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--;
-       } else {
-         eset_insert(env->call_nodes, call);
-       }
+        inline_irg_env *callee_env;
+        ir_graph *callee = get_call_called_irg(call);
+
+        if (env->n_nodes > maxsize) break;
+        if (callee && is_leave(callee) && is_smaller(callee, leavesize)) {
+          if (!phiproj_computed) {
+            phiproj_computed = 1;
+            collect_phiprojs(current_ir_graph);
+          }
+          callee_env = (inline_irg_env *)get_irg_link(callee);
+//        printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)),
+//           get_entity_name(get_irg_entity(callee)));
+          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--;
+        } else {
+          eset_insert(env->call_nodes, call);
+        }
       }
       eset_destroy(walkset);
     }
@@ -1085,25 +1159,27 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
     walkset = env->call_nodes;
     env->call_nodes = eset_create();
     for (call = eset_first(walkset); call; call = eset_next(walkset)) {
+      inline_irg_env *callee_env;
       ir_graph *callee = get_call_called_irg(call);
+
       if (env->n_nodes > maxsize) break;
       if (callee && is_smaller(callee, size)) {
-       if (!phiproj_computed) {
-         phiproj_computed = 1;
-         collect_phiprojs(current_ir_graph);
-       }
-       inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
-       //printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)),
-       //       get_entity_name(get_irg_entity(callee)));
-       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--;
+        if (!phiproj_computed) {
+               phiproj_computed = 1;
+               collect_phiprojs(current_ir_graph);
+        }
+        callee_env = (inline_irg_env *)get_irg_link(callee);
+//      printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)),
+//      get_entity_name(get_irg_entity(callee)));
+        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--;
       } else {
-       eset_insert(env->call_nodes, call);
+        eset_insert(env->call_nodes, call);
       }
     }
     eset_destroy(walkset);
@@ -1127,16 +1203,14 @@ void inline_leave_functions(int maxsize, int leavesize, int size) {
 }
 
 /********************************************************************/
-/*  Code Placement.  Pinns all floating nodes to a block where they */
+/*  Code Placement.  Pins all floating nodes to a block where they */
 /*  will be executed only if needed.                                */
 /********************************************************************/
 
-static pdeq *worklist;         /* worklist of ir_node*s */
-
 /* Find the earliest correct block for N.  --- Place N into the
    same Block as its dominance-deepest Input.  */
 static void
-place_floats_early (ir_node *n)
+place_floats_early(ir_node *n, pdeq *worklist)
 {
   int i, start, irn_arity;
 
@@ -1167,7 +1241,7 @@ place_floats_early (ir_node *n)
       ir_node *dep_block;
       if ((irn_not_visited(dep)) &&
          (get_op_pinned(get_irn_op(dep)) == floats)) {
-       place_floats_early (dep);
+       place_floats_early(dep, worklist);
       }
       /* Because all loops contain at least one pinned node, now all
          our inputs are either pinned or place_early has already
@@ -1203,17 +1277,17 @@ place_floats_early (ir_node *n)
    Start, Call and 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. */
-static INLINE void place_early (void) {
+static INLINE void place_early(pdeq* worklist) {
   assert(worklist);
   inc_irg_visited(current_ir_graph);
 
   /* this inits the worklist */
-  place_floats_early (get_irg_end(current_ir_graph));
+  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);
+    if (irn_not_visited(n)) place_floats_early(n, worklist);
   }
 
   set_irg_outs_inconsistent(current_ir_graph);
@@ -1230,7 +1304,7 @@ consumer_dom_dca (ir_node *dca, ir_node *consumer, ir_node *producer)
   /* Compute the latest block into which we can place a node so that it is
      before consumer. */
   if (get_irn_op(consumer) == op_Phi) {
-    /* our comsumer is a Phi-node, the effective use is in all those
+    /* our consumer is a Phi-node, the effective use is in all those
        blocks through which the Phi-node reaches producer */
     int i, irn_arity;
     ir_node *phi_block = get_nodes_Block(consumer);
@@ -1298,10 +1372,10 @@ move_out_of_loops (ir_node *n, ir_node *early)
    `optimal' Block between the latest and earliest legal block.
    The `optimal' block is the dominance-deepest block of those
    with the least loop-nesting-depth.  This places N out of as many
-   loops as possible and then makes it as controldependant as
+   loops as possible and then makes it as control dependant as
    possible. */
 static void
-place_floats_late (ir_node *n)
+place_floats_late(ir_node *n, pdeq *worklist)
 {
   int i;
   ir_node *early;
@@ -1312,13 +1386,13 @@ place_floats_late (ir_node *n)
   if ((get_irn_op(n) != op_Block) &&
       (!is_cfop(n)) &&
       (get_irn_mode(n) != mode_X)) {
-    /* Remember the early palacement of this block to move it
+    /* Remember the early placement of this block to move it
        out of loop no further than the early placement. */
     early = get_nodes_Block(n);
     /* Assure that our users are all placed, except the Phi-nodes.
-       --- Each dataflow cycle contains at least one Phi-node.  We
+       --- Each data flow cycle contains at least one Phi-node.  We
        have to break the `user has to be placed before the
-       producer' dependance cycle and the Phi-nodes are the
+       producer' dependence cycle and the Phi-nodes are the
        place to do so, because we need to base our placement on the
        final region of our users, which is OK with Phi-nodes, as they
        are pinned, and they never have to be placed after a
@@ -1326,7 +1400,7 @@ place_floats_late (ir_node *n)
     for (i = 0; i < get_irn_n_outs(n); i++) {
       ir_node *succ = get_irn_out(n, i);
       if (irn_not_visited(succ) && (get_irn_op(succ) != op_Phi))
-       place_floats_late (succ);
+       place_floats_late(succ, worklist);
     }
 
     /* We have to determine the final block of this node... except for
@@ -1358,21 +1432,23 @@ place_floats_late (ir_node *n)
   }
 }
 
-static INLINE void place_late(void) {
+static INLINE void place_late(pdeq* worklist) {
   assert(worklist);
   inc_irg_visited(current_ir_graph);
 
   /* This fills the worklist initially. */
-  place_floats_late(get_irg_start_block(current_ir_graph));
+  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);
+    if (irn_not_visited(n)) place_floats_late(n, worklist);
   }
 }
 
 void place_code(ir_graph *irg) {
+  pdeq* worklist;
   ir_graph *rem = current_ir_graph;
+
   current_ir_graph = irg;
 
   if (!(get_optimize() && get_opt_global_cse())) return;
@@ -1386,17 +1462,17 @@ void place_code(ir_graph *irg) {
 
   /* Place all floating nodes as early as possible. This guarantees
      a legal code placement. */
-  worklist = new_pdeq ();
-  place_early();
+  worklist = new_pdeq();
+  place_early(worklist);
 
   /* place_early invalidates the outs, place_late needs them. */
   compute_outs(irg);
   /* Now move the nodes down in the dominator tree. This reduces the
      unnecessary executions of the node. */
-  place_late();
+  place_late(worklist);
 
   set_irg_outs_inconsistent(current_ir_graph);
-  del_pdeq (worklist);
+  del_pdeq(worklist);
   current_ir_graph = rem;
 }
 
@@ -1420,27 +1496,27 @@ static void merge_blocks(ir_node *n, void *env) {
   if (get_irn_op(n) == op_Block) {
     /* Remove Tuples */
     for (i = 0; i < get_Block_n_cfgpreds(n); i++)
-      /* GL @@@ : is this possible? if (get_opt_normalize()) -- added, all tests go throug.
+      /* 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)));
   } else if (get_optimize() && (get_irn_mode(n) == mode_X)) {
     /* We will soon visit a block.  Optimize it before visiting! */
     ir_node *b = get_nodes_Block(n);
-    ir_node *new = equivalent_node(b);
-    while (irn_not_visited(b) && (!is_Bad(new)) && (new != b)) {
+    ir_node *new_node = equivalent_node(b);
+    while (irn_not_visited(b) && (!is_Bad(new_node)) && (new_node != b)) {
       /* We would have to run gigo if new is bad, so we
         promote it directly below. */
-      assert(((b == new) ||
+      assert(((b == new_node) ||
              get_opt_control_flow_straightening() ||
              get_opt_control_flow_weak_simplification()) &&
             ("strange flag setting"));
-      exchange (b, new);
-      b = new;
-      new = equivalent_node(b);
+      exchange (b, new_node);
+      b = new_node;
+      new_node = equivalent_node(b);
     }
     /* GL @@@ get_opt_normalize hinzugefuegt, 5.5.2003 */
-    if (is_Bad(new) && get_opt_normalize()) exchange (n, new_Bad());
+    if (is_Bad(new_node) && get_opt_normalize()) exchange(n, new_Bad());
   }
 }
 
@@ -1727,10 +1803,10 @@ void optimize_cf(ir_graph *irg) {
  * Called by walker of remove_critical_cf_edges.
  *
  * Place an empty block to an edge between a blocks of multiple
- * predecessors and a block of multiple sucessors.
+ * predecessors and a block of multiple successors.
  *
  * @param n IR node
- * @param env Envirnment of walker. This field is unused and has
+ * @param env Environment of walker. This field is unused and has
  *            the value NULL.
  */
 static void walk_critical_cf_edges(ir_node *n, void *env) {
@@ -1747,7 +1823,7 @@ static void walk_critical_cf_edges(ir_node *n, void *env) {
 
     for (i=0; i<arity; i++) {
       pre = get_irn_n(n, i);
-      /* Predecessor has multiple sucessors. Insert new flow edge */
+      /* 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))) {
@@ -1761,10 +1837,10 @@ static void walk_critical_cf_edges(ir_node *n, void *env) {
        switch_block(block);
        jmp = new_Jmp();
        switch_block(n);
-       /* set sucessor of new block */
+       /* set successor of new block */
        set_irn_n(n, i, jmp);
 
-      } /* predecessor has multiple sucessors */
+      } /* predecessor has multiple successors */
     } /* for all predecessors */
   } /* n is a block */
 }