extern "C" added
[libfirm] / ir / ir / irgopt.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irgopt.c
4  * Purpose:     Optimizations for a whole ir graph, i.e., a procedure.
5  * Author:      Christian Schaefer, Goetz Lindenmaier
6  * Modified by: Sebastian Felis
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13
14 #ifdef HAVE_CONFIG_H
15 # include "config.h"
16 #endif
17
18 #include <assert.h>
19
20 #include "irnode_t.h"
21 #include "irgraph_t.h"
22 #include "irprog_t.h"
23
24 #include "ircons.h"
25 #include "iropt_t.h"
26 #include "irgopt.h"
27 #include "irgmod.h"
28 #include "irgwalk.h"
29
30 #include "array.h"
31 #include "pset.h"
32 #include "eset.h"
33 #include "pdeq.h"       /* Fuer code placement */
34 #include "xmalloc.h"
35
36 #include "irouts.h"
37 #include "irloop_t.h"
38 #include "irbackedge_t.h"
39 #include "cgana.h"
40 #include "trouts.h"
41
42 #include "irflag_t.h"
43 #include "irhooks.h"
44 #include "iredges_t.h"
45 #include "irtools.h"
46
47 /* Defined in iropt.c */
48 pset *new_identities (void);
49 void  del_identities (pset *value_table);
50 void  add_identities   (pset *value_table, ir_node *node);
51
52 /*------------------------------------------------------------------*/
53 /* apply optimizations of iropt to all nodes.                       */
54 /*------------------------------------------------------------------*/
55
56 static void init_link (ir_node *n, void *env) {
57   set_irn_link(n, NULL);
58 }
59
60 #if 0   /* Old version. Avoids Ids.
61            This is not necessary:  we do a post walk, and get_irn_n
62            removes ids anyways.  So it's much cheaper to call the
63            optimization less often and use the exchange() algorithm. */
64 static void
65 optimize_in_place_wrapper (ir_node *n, void *env) {
66   int i, irn_arity;
67   ir_node *optimized, *old;
68
69   irn_arity = get_irn_arity(n);
70   for (i = 0; i < irn_arity; i++) {
71     /* get_irn_n skips Id nodes, so comparison old != optimized does not
72        show all optimizations. Therefore always set new predecessor. */
73     old = get_irn_intra_n(n, i);
74     optimized = optimize_in_place_2(old);
75     set_irn_n(n, i, optimized);
76   }
77
78   if (get_irn_op(n) == op_Block) {
79     optimized = optimize_in_place_2(n);
80     if (optimized != n) exchange (n, optimized);
81   }
82 }
83 #else
84 static void
85 optimize_in_place_wrapper (ir_node *n, void *env) {
86   ir_node *optimized = optimize_in_place_2(n);
87   if (optimized != n) exchange (n, optimized);
88 }
89 #endif
90
91
92 static INLINE void do_local_optimize(ir_node *n) {
93   /* Handle graph state */
94   assert(get_irg_phase_state(current_ir_graph) != phase_building);
95
96   if (get_opt_global_cse())
97     set_irg_pinned(current_ir_graph, op_pin_state_floats);
98   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
99     set_irg_outs_inconsistent(current_ir_graph);
100   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
101     set_irg_dom_inconsistent(current_ir_graph);
102   set_irg_loopinfo_inconsistent(current_ir_graph);
103
104   /* Clean the value_table in irg for the CSE. */
105   del_identities(current_ir_graph->value_table);
106   current_ir_graph->value_table = new_identities();
107
108   /* walk over the graph */
109   irg_walk(n, init_link, optimize_in_place_wrapper, NULL);
110 }
111
112 void local_optimize_node(ir_node *n) {
113   ir_graph *rem = current_ir_graph;
114   current_ir_graph = get_irn_irg(n);
115
116   do_local_optimize(n);
117
118   current_ir_graph = rem;
119 }
120
121 /**
122  * Block-Walker: uses dominance depth to mark dead blocks.
123  */
124 static void kill_dead_blocks(ir_node *block, void *env)
125 {
126   if (get_Block_dom_depth(block) < 0)
127     set_Block_dead(block);
128 }
129
130 void
131 local_optimize_graph (ir_graph *irg) {
132   ir_graph *rem = current_ir_graph;
133   current_ir_graph = irg;
134
135   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
136     irg_block_walk_graph(irg, NULL, kill_dead_blocks, NULL);
137
138   do_local_optimize(irg->end);
139
140   current_ir_graph = rem;
141 }
142
143
144 /*------------------------------------------------------------------*/
145 /* Routines for dead node elimination / copying garbage collection  */
146 /* of the obstack.                                                  */
147 /*------------------------------------------------------------------*/
148
149 /**
150  * Remember the new node in the old node by using a field all nodes have.
151  */
152 static INLINE void
153 set_new_node (ir_node *old, ir_node *new)
154 {
155   old->link = new;
156 }
157
158 /**
159  * Get this new node, before the old node is forgotten.
160  */
161 static INLINE ir_node *
162 get_new_node (ir_node * n) {
163   return n->link;
164 }
165
166 /**
167  * We use the block_visited flag to mark that we have computed the
168  * number of useful predecessors for this block.
169  * Further we encode the new arity in this flag in the old blocks.
170  * Remembering the arity is useful, as it saves a lot of pointer
171  * accesses.  This function is called for all Phi and Block nodes
172  * in a Block.
173  */
174 static INLINE int
175 compute_new_arity(ir_node *b) {
176   int i, res, irn_arity;
177   int irg_v, block_v;
178
179   irg_v = get_irg_block_visited(current_ir_graph);
180   block_v = get_Block_block_visited(b);
181   if (block_v >= irg_v) {
182     /* we computed the number of preds for this block and saved it in the
183        block_v flag */
184     return block_v - irg_v;
185   } else {
186     /* compute the number of good predecessors */
187     res = irn_arity = get_irn_arity(b);
188     for (i = 0; i < irn_arity; i++)
189       if (get_irn_opcode(get_irn_n(b, i)) == iro_Bad) res--;
190     /* save it in the flag. */
191     set_Block_block_visited(b, irg_v + res);
192     return res;
193   }
194 }
195
196 /**
197  * Copies the node to the new obstack. The Ins of the new node point to
198  * the predecessors on the old obstack.  For block/phi nodes not all
199  * predecessors might be copied.  n->link points to the new node.
200  * For Phi and Block nodes the function allocates in-arrays with an arity
201  * only for useful predecessors.  The arity is determined by counting
202  * the non-bad predecessors of the block.
203  *
204  * @param n    The node to be copied
205  * @param env  if non-NULL, the node number attribute will be copied to the new node
206  *
207  * Note: Also used for loop unrolling.
208  */
209 static void copy_node(ir_node *n, void *env) {
210   ir_node *nn, *block;
211   int new_arity;
212   ir_op *op = get_irn_op(n);
213   int copy_node_nr = env != NULL;
214
215   /* The end node looses it's flexible in array.  This doesn't matter,
216      as dead node elimination builds End by hand, inlineing doesn't use
217      the End node. */
218   /* assert(op == op_End ||  ((_ARR_DESCR(n->in))->cookie != ARR_F_MAGIC)); */
219
220   if (op == op_Bad) {
221     /* node copied already */
222     return;
223   } else if (op == op_Block) {
224     block = NULL;
225     new_arity = compute_new_arity(n);
226     n->attr.block.graph_arr = NULL;
227   } else {
228     block = get_nodes_block(n);
229     if (op == op_Phi) {
230       new_arity = compute_new_arity(block);
231     } else {
232       new_arity = get_irn_arity(n);
233     }
234   }
235   nn = new_ir_node(get_irn_dbg_info(n),
236            current_ir_graph,
237            block,
238            op,
239            get_irn_mode(n),
240            new_arity,
241            get_irn_in(n) + 1);
242   /* Copy the attributes.  These might point to additional data.  If this
243      was allocated on the old obstack the pointers now are dangling.  This
244      frees e.g. the memory of the graph_arr allocated in new_immBlock. */
245   copy_node_attr(n, nn);
246   new_backedge_info(nn);
247
248 #if DEBUG_libfirm
249   if (copy_node_nr) {
250     /* for easier debugging, we want to copy the node numbers too */
251     nn->node_nr = n->node_nr;
252   }
253 #endif
254
255   set_new_node(n, nn);
256 }
257
258 /**
259  * Copies new predecessors of old node to new node remembered in link.
260  * Spare the Bad predecessors of Phi and Block nodes.
261  */
262 void
263 copy_preds (ir_node *n, void *env) {
264   ir_node *nn, *block;
265   int i, j, irn_arity;
266
267   nn = get_new_node(n);
268
269   /* printf("\n old node: "); DDMSG2(n);
270      printf(" new node: "); DDMSG2(nn);
271      printf(" arities: old: %d, new: %d\n", get_irn_arity(n), get_irn_arity(nn)); */
272
273   if (is_Block(n)) {
274     /* Don't copy Bad nodes. */
275     j = 0;
276     irn_arity = get_irn_arity(n);
277     for (i = 0; i < irn_arity; i++)
278       if (! is_Bad(get_irn_n(n, i))) {
279         set_irn_n (nn, j, get_new_node(get_irn_n(n, i)));
280         /*if (is_backedge(n, i)) set_backedge(nn, j);*/
281         j++;
282       }
283     /* repair the block visited flag from above misuse. Repair it in both
284        graphs so that the old one can still be used. */
285     set_Block_block_visited(nn, 0);
286     set_Block_block_visited(n, 0);
287     /* Local optimization could not merge two subsequent blocks if
288        in array contained Bads.  Now it's possible.
289        We don't call optimize_in_place as it requires
290        that the fields in ir_graph are set properly. */
291     if ((get_opt_control_flow_straightening()) &&
292         (get_Block_n_cfgpreds(nn) == 1) &&
293         (get_irn_op(get_Block_cfgpred(nn, 0)) == op_Jmp)) {
294       ir_node *old = get_nodes_block(get_Block_cfgpred(nn, 0));
295       if (nn == old) {
296         /* Jmp jumps into the block it is in -- deal self cycle. */
297         assert(is_Bad(get_new_node(get_irg_bad(current_ir_graph))));
298         exchange(nn, get_new_node(get_irg_bad(current_ir_graph)));
299       } else {
300         exchange(nn, old);
301       }
302     }
303   } else if (get_irn_op(n) == op_Phi) {
304     /* Don't copy node if corresponding predecessor in block is Bad.
305        The Block itself should not be Bad. */
306     block = get_nodes_block(n);
307     set_irn_n (nn, -1, get_new_node(block));
308     j = 0;
309     irn_arity = get_irn_arity(n);
310     for (i = 0; i < irn_arity; i++)
311       if (! is_Bad(get_irn_n(block, i))) {
312         set_irn_n (nn, j, get_new_node(get_irn_n(n, i)));
313         /*if (is_backedge(n, i)) set_backedge(nn, j);*/
314         j++;
315       }
316     /* If the pre walker reached this Phi after the post walker visited the
317        block block_visited is > 0. */
318     set_Block_block_visited(get_nodes_block(n), 0);
319     /* Compacting the Phi's ins might generate Phis with only one
320        predecessor. */
321     if (get_irn_arity(nn) == 1)
322       exchange(nn, get_irn_n(nn, 0));
323   } else {
324     irn_arity = get_irn_arity(n);
325     for (i = -1; i < irn_arity; i++)
326       set_irn_n (nn, i, get_new_node(get_irn_n(n, i)));
327   }
328   /* Now the new node is complete.  We can add it to the hash table for CSE.
329      @@@ inlinening aborts if we identify End. Why? */
330   if (get_irn_op(nn) != op_End)
331     add_identities (current_ir_graph->value_table, nn);
332 }
333
334 /**
335  * Copies the graph recursively, compacts the keepalive of the end node.
336  *
337  * @param copy_node_nr  If non-zero, the node number will be copied
338  */
339 static void
340 copy_graph (int copy_node_nr) {
341   ir_node *oe, *ne, *ob, *nb, *om, *nm; /* old end, new end, old bad, new bad, old NoMem, new NoMem */
342   ir_node *ka;      /* keep alive */
343   int i, irn_arity;
344
345   oe = get_irg_end(current_ir_graph);
346   /* copy the end node by hand, allocate dynamic in array! */
347   ne = new_ir_node(get_irn_dbg_info(oe),
348            current_ir_graph,
349            NULL,
350            op_End,
351            mode_X,
352            -1,
353            NULL);
354   /* Copy the attributes.  Well, there might be some in the future... */
355   copy_node_attr(oe, ne);
356   set_new_node(oe, ne);
357
358   /* copy the Bad node */
359   ob = get_irg_bad(current_ir_graph);
360   nb =  new_ir_node(get_irn_dbg_info(ob),
361            current_ir_graph,
362            NULL,
363            op_Bad,
364            mode_T,
365            0,
366            NULL);
367   set_new_node(ob, nb);
368
369   /* copy the NoMem node */
370   om = get_irg_no_mem(current_ir_graph);
371   nm =  new_ir_node(get_irn_dbg_info(om),
372            current_ir_graph,
373            NULL,
374            op_NoMem,
375            mode_M,
376            0,
377            NULL);
378   set_new_node(om, nm);
379
380   /* copy the live nodes */
381   irg_walk(get_nodes_block(oe), copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
382   /* copy_preds for the end node ... */
383   set_nodes_block(ne, get_new_node(get_nodes_block(oe)));
384
385   /*- ... and now the keep alives. -*/
386   /* First pick the not marked block nodes and walk them.  We must pick these
387      first as else we will oversee blocks reachable from Phis. */
388   irn_arity = get_irn_arity(oe);
389   for (i = 0; i < irn_arity; i++) {
390     ka = get_irn_intra_n(oe, i);
391     if ((get_irn_op(ka) == op_Block) &&
392         (get_irn_visited(ka) < get_irg_visited(current_ir_graph))) {
393       /* We must keep the block alive and copy everything reachable */
394       set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
395       irg_walk(ka, copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
396       add_End_keepalive(ne, get_new_node(ka));
397     }
398   }
399
400   /* Now pick the Phis.  Here we will keep all! */
401   irn_arity = get_irn_arity(oe);
402   for (i = 0; i < irn_arity; i++) {
403     ka = get_irn_intra_n(oe, i);
404     if ((get_irn_op(ka) == op_Phi)) {
405       if (get_irn_visited(ka) < get_irg_visited(current_ir_graph)) {
406         /* We didn't copy the Phi yet.  */
407         set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
408         irg_walk(ka, copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
409       }
410       add_End_keepalive(ne, get_new_node(ka));
411     }
412   }
413
414   /* start block sometimes only reached after keep alives */
415   set_nodes_block(nb, get_new_node(get_nodes_block(ob)));
416   set_nodes_block(nm, get_new_node(get_nodes_block(om)));
417 }
418
419 /**
420  * Copies the graph reachable from current_ir_graph->end to the obstack
421  * in current_ir_graph and fixes the environment.
422  * Then fixes the fields in current_ir_graph containing nodes of the
423  * graph.
424  *
425  * @param copy_node_nr  If non-zero, the node number will be copied
426  */
427 static void
428 copy_graph_env (int copy_node_nr) {
429   ir_node *old_end;
430   /* Not all nodes remembered in current_ir_graph might be reachable
431      from the end node.  Assure their link is set to NULL, so that
432      we can test whether new nodes have been computed. */
433   set_irn_link(get_irg_frame      (current_ir_graph), NULL);
434   set_irn_link(get_irg_globals    (current_ir_graph), NULL);
435   set_irn_link(get_irg_args       (current_ir_graph), NULL);
436   set_irn_link(get_irg_initial_mem(current_ir_graph), NULL);
437   set_irn_link(get_irg_bad        (current_ir_graph), NULL);
438   set_irn_link(get_irg_no_mem     (current_ir_graph), NULL);
439
440   /* we use the block walk flag for removing Bads from Blocks ins. */
441   inc_irg_block_visited(current_ir_graph);
442
443   /* copy the graph */
444   copy_graph(copy_node_nr);
445
446   /* fix the fields in current_ir_graph */
447   old_end = get_irg_end(current_ir_graph);
448   set_irg_end        (current_ir_graph, get_new_node(old_end));
449   set_irg_end_except (current_ir_graph, get_irg_end(current_ir_graph));
450   set_irg_end_reg    (current_ir_graph, get_irg_end(current_ir_graph));
451   free_End(old_end);
452   set_irg_end_block  (current_ir_graph, get_new_node(get_irg_end_block(current_ir_graph)));
453
454   if (get_irn_link(get_irg_frame(current_ir_graph)) == NULL) {
455     copy_node (get_irg_frame(current_ir_graph), INT_TO_PTR(copy_node_nr));
456     copy_preds(get_irg_frame(current_ir_graph), NULL);
457   }
458   if (get_irn_link(get_irg_globals(current_ir_graph)) == NULL) {
459     copy_node (get_irg_globals(current_ir_graph), INT_TO_PTR(copy_node_nr));
460     copy_preds(get_irg_globals(current_ir_graph), NULL);
461   }
462   if (get_irn_link(get_irg_initial_mem(current_ir_graph)) == NULL) {
463     copy_node (get_irg_initial_mem(current_ir_graph), INT_TO_PTR(copy_node_nr));
464     copy_preds(get_irg_initial_mem(current_ir_graph), NULL);
465   }
466   if (get_irn_link(get_irg_args(current_ir_graph)) == NULL) {
467     copy_node (get_irg_args(current_ir_graph), INT_TO_PTR(copy_node_nr));
468     copy_preds(get_irg_args(current_ir_graph), NULL);
469   }
470   if (get_irn_link(get_irg_bad(current_ir_graph)) == NULL) {
471     copy_node(get_irg_bad(current_ir_graph), INT_TO_PTR(copy_node_nr));
472     copy_preds(get_irg_bad(current_ir_graph), NULL);
473   }
474   if (get_irn_link(get_irg_no_mem(current_ir_graph)) == NULL) {
475     copy_node(get_irg_no_mem(current_ir_graph), INT_TO_PTR(copy_node_nr));
476     copy_preds(get_irg_no_mem(current_ir_graph), NULL);
477   }
478   set_irg_start      (current_ir_graph, get_new_node(get_irg_start(current_ir_graph)));
479   set_irg_start_block(current_ir_graph, get_new_node(get_irg_start_block(current_ir_graph)));
480   set_irg_frame      (current_ir_graph, get_new_node(get_irg_frame(current_ir_graph)));
481   set_irg_globals    (current_ir_graph, get_new_node(get_irg_globals(current_ir_graph)));
482   set_irg_initial_mem(current_ir_graph, get_new_node(get_irg_initial_mem(current_ir_graph)));
483   set_irg_args       (current_ir_graph, get_new_node(get_irg_args(current_ir_graph)));
484   set_irg_bad        (current_ir_graph, get_new_node(get_irg_bad(current_ir_graph)));
485   set_irg_no_mem     (current_ir_graph, get_new_node(get_irg_no_mem(current_ir_graph)));
486 }
487
488 /**
489  * Copies all reachable nodes to a new obstack.  Removes bad inputs
490  * from block nodes and the corresponding inputs from Phi nodes.
491  * Merges single exit blocks with single entry blocks and removes
492  * 1-input Phis.
493  * Adds all new nodes to a new hash table for CSE.  Does not
494  * perform CSE, so the hash table might contain common subexpressions.
495  */
496 void
497 dead_node_elimination(ir_graph *irg) {
498   ir_graph *rem;
499   int rem_ipview = get_interprocedural_view();
500   struct obstack *graveyard_obst = NULL;
501   struct obstack *rebirth_obst   = NULL;
502
503   if (get_opt_optimize() && get_opt_dead_node_elimination()) {
504     assert(! edges_activated(irg) && "dead node elimination requieres disabled edges");
505
506     /* inform statistics that we started a dead-node elimination run */
507     hook_dead_node_elim(irg, 1);
508
509     /* Remember external state of current_ir_graph. */
510     rem = current_ir_graph;
511     current_ir_graph = irg;
512     set_interprocedural_view(0);
513
514     assert(get_irg_phase_state(current_ir_graph) != phase_building);
515
516     /* Handle graph state */
517     free_callee_info(current_ir_graph);
518     free_irg_outs(current_ir_graph);
519     free_trouts();
520
521     /* @@@ so far we loose loops when copying */
522     free_loop_information(current_ir_graph);
523
524     if (get_irg_dom_state(irg) != dom_none)
525       set_irg_dom_inconsistent(irg);
526
527     /* A quiet place, where the old obstack can rest in peace,
528        until it will be cremated. */
529     graveyard_obst = irg->obst;
530
531     /* A new obstack, where the reachable nodes will be copied to. */
532     rebirth_obst = xmalloc (sizeof(*rebirth_obst));
533     current_ir_graph->obst = rebirth_obst;
534     obstack_init (current_ir_graph->obst);
535
536     /* We also need a new hash table for cse */
537     del_identities (irg->value_table);
538     irg->value_table = new_identities ();
539
540     /* Copy the graph from the old to the new obstack */
541     copy_graph_env(1);
542
543     /* Free memory from old unoptimized obstack */
544     obstack_free(graveyard_obst, 0);  /* First empty the obstack ... */
545     xfree (graveyard_obst);           /* ... then free it.           */
546
547     /* inform statistics that the run is over */
548     hook_dead_node_elim(irg, 0);
549
550     current_ir_graph = rem;
551     set_interprocedural_view(rem_ipview);
552   }
553 }
554
555 /**
556  * Relink bad predecessors of a block and store the old in array to the
557  * link field. This function is called by relink_bad_predecessors().
558  * The array of link field starts with the block operand at position 0.
559  * If block has bad predecessors, create a new in array without bad preds.
560  * Otherwise let in array untouched.
561  */
562 static void relink_bad_block_predecessors(ir_node *n, void *env) {
563   ir_node **new_in, *irn;
564   int i, new_irn_n, old_irn_arity, new_irn_arity = 0;
565
566   /* if link field of block is NULL, look for bad predecessors otherwise
567      this is already done */
568   if (get_irn_op(n) == op_Block &&
569       get_irn_link(n) == NULL) {
570
571     /* save old predecessors in link field (position 0 is the block operand)*/
572     set_irn_link(n, get_irn_in(n));
573
574     /* count predecessors without bad nodes */
575     old_irn_arity = get_irn_arity(n);
576     for (i = 0; i < old_irn_arity; i++)
577       if (!is_Bad(get_irn_n(n, i))) new_irn_arity++;
578
579     /* arity changing: set new predecessors without bad nodes */
580     if (new_irn_arity < old_irn_arity) {
581       /* Get new predecessor array. We do not resize the array, as we must
582          keep the old one to update Phis. */
583       new_in = NEW_ARR_D (ir_node *, current_ir_graph->obst, (new_irn_arity+1));
584
585       /* set new predecessors in array */
586       new_in[0] = NULL;
587       new_irn_n = 1;
588       for (i = 0; i < old_irn_arity; i++) {
589         irn = get_irn_n(n, i);
590         if (!is_Bad(irn)) {
591           new_in[new_irn_n] = irn;
592           is_backedge(n, i) ? set_backedge(n, new_irn_n-1) : set_not_backedge(n, new_irn_n-1);
593           ++new_irn_n;
594         }
595       }
596       //ARR_SETLEN(int, n->attr.block.backedge, new_irn_arity);
597       ARR_SHRINKLEN(n->attr.block.backedge, new_irn_arity);
598       n->in = new_in;
599
600     } /* ir node has bad predecessors */
601
602   } /* Block is not relinked */
603 }
604
605 /**
606  * Relinks Bad predecessors from Blocks and Phis called by walker
607  * remove_bad_predecesors(). If n is a Block, call
608  * relink_bad_block_redecessors(). If n is a Phi-node, call also the relinking
609  * function of Phi's Block. If this block has bad predecessors, relink preds
610  * of the Phi-node.
611  */
612 static void relink_bad_predecessors(ir_node *n, void *env) {
613   ir_node *block, **old_in;
614   int i, old_irn_arity, new_irn_arity;
615
616   /* relink bad predecessors of a block */
617   if (get_irn_op(n) == op_Block)
618     relink_bad_block_predecessors(n, env);
619
620   /* If Phi node relink its block and its predecessors */
621   if (get_irn_op(n) == op_Phi) {
622
623     /* Relink predecessors of phi's block */
624     block = get_nodes_block(n);
625     if (get_irn_link(block) == NULL)
626       relink_bad_block_predecessors(block, env);
627
628     old_in = (ir_node **)get_irn_link(block); /* Of Phi's Block */
629     old_irn_arity = ARR_LEN(old_in);
630
631     /* Relink Phi predecessors if count of predecessors changed */
632     if (old_irn_arity != ARR_LEN(get_irn_in(block))) {
633       /* set new predecessors in array
634          n->in[0] remains the same block */
635       new_irn_arity = 1;
636       for(i = 1; i < old_irn_arity; i++)
637         if (!is_Bad((ir_node *)old_in[i])) {
638           n->in[new_irn_arity] = n->in[i];
639           is_backedge(n, i) ? set_backedge(n, new_irn_arity) : set_not_backedge(n, new_irn_arity);
640           ++new_irn_arity;
641         }
642
643       ARR_SETLEN(ir_node *, n->in, new_irn_arity);
644       ARR_SETLEN(int, n->attr.phi_backedge, new_irn_arity);
645     }
646
647   } /* n is a Phi node */
648 }
649
650 /*
651  * Removes Bad Bad predecessors from Blocks and the corresponding
652  * inputs to Phi nodes as in dead_node_elimination but without
653  * copying the graph.
654  * On walking up set the link field to NULL, on walking down call
655  * relink_bad_predecessors() (This function stores the old in array
656  * to the link field and sets a new in array if arity of predecessors
657  * changes).
658  */
659 void remove_bad_predecessors(ir_graph *irg) {
660   irg_walk_graph(irg, init_link, relink_bad_predecessors, NULL);
661 }
662
663
664 /*--------------------------------------------------------------------*/
665 /*  Functionality for inlining                                         */
666 /*--------------------------------------------------------------------*/
667
668 /**
669  * Copy node for inlineing.  Updates attributes that change when
670  * inlineing but not for dead node elimination.
671  *
672  * Copies the node by calling copy_node() and then updates the entity if
673  * it's a local one.  env must be a pointer of the frame type of the
674  * inlined procedure. The new entities must be in the link field of
675  * the entities.
676  */
677 static INLINE void
678 copy_node_inline (ir_node *n, void *env) {
679   ir_node *new;
680   type *frame_tp = (type *)env;
681
682   copy_node(n, NULL);
683   if (get_irn_op(n) == op_Sel) {
684     new = get_new_node (n);
685     assert(get_irn_op(new) == op_Sel);
686     if (get_entity_owner(get_Sel_entity(n)) == frame_tp) {
687       set_Sel_entity(new, get_entity_link(get_Sel_entity(n)));
688     }
689   } else if (get_irn_op(n) == op_Block) {
690     new = get_new_node (n);
691     new->attr.block.irg = current_ir_graph;
692   }
693 }
694
695 static void find_addr(ir_node *node, void *env)
696 {
697   if (get_irn_opcode(node) == iro_Proj) {
698     if (get_Proj_proj(node) == pn_Start_P_value_arg_base)
699       *(int *)env = 0;
700   }
701 }
702
703 /*
704  * currently, we cannot inline two cases:
705  * - call with compound arguments
706  * - graphs that take the address of a parameter
707  *
708  * check these conditions here
709  */
710 static int can_inline(ir_node *call, ir_graph *called_graph)
711 {
712   type *call_type = get_Call_type(call);
713   int params, ress, i, res;
714   assert(is_Method_type(call_type));
715
716   params = get_method_n_params(call_type);
717   ress   = get_method_n_ress(call_type);
718
719   /* check params */
720   for (i = 0; i < params; ++i) {
721     type *p_type = get_method_param_type(call_type, i);
722
723     if (is_compound_type(p_type))
724       return 0;
725   }
726
727   /* check res */
728   for (i = 0; i < ress; ++i) {
729     type *r_type = get_method_res_type(call_type, i);
730
731     if (is_compound_type(r_type))
732       return 0;
733   }
734
735   res = 1;
736   irg_walk_graph(called_graph, find_addr, NULL, &res);
737
738   return res;
739 }
740
741 int inline_method(ir_node *call, ir_graph *called_graph) {
742   ir_node *pre_call;
743   ir_node *post_call, *post_bl;
744   ir_node *in[5];
745   ir_node *end, *end_bl;
746   ir_node **res_pred;
747   ir_node **cf_pred;
748   ir_node *ret, *phi;
749   int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity;
750   int exc_handling;
751   type *called_frame;
752   irg_inline_property prop = get_irg_inline_property(called_graph);
753
754   if ( (prop != irg_inline_forced) &&
755        (!get_opt_optimize() || !get_opt_inline() || (prop == irg_inline_forbidden))) return 0;
756
757   /* Do not inline variadic functions. */
758   if (get_method_variadicity(get_entity_type(get_irg_entity(called_graph))) == variadicity_variadic)
759     return 0;
760
761   assert(get_method_n_params(get_entity_type(get_irg_entity(called_graph))) ==
762          get_method_n_params(get_Call_type(call)));
763
764   /*
765    * currently, we cannot inline two cases:
766    * - call with compound arguments
767    * - graphs that take the address of a parameter
768    */
769   if (! can_inline(call, called_graph))
770     return 0;
771
772   /* --  Turn off optimizations, this can cause problems when allocating new nodes. -- */
773   rem_opt = get_opt_optimize();
774   set_optimize(0);
775
776   /* Handle graph state */
777   assert(get_irg_phase_state(current_ir_graph) != phase_building);
778   assert(get_irg_pinned(current_ir_graph) == op_pin_state_pinned);
779   assert(get_irg_pinned(called_graph) == op_pin_state_pinned);
780   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
781     set_irg_outs_inconsistent(current_ir_graph);
782   set_irg_loopinfo_inconsistent(current_ir_graph);
783   set_irg_callee_info_state(current_ir_graph, irg_callee_info_inconsistent);
784
785   /* -- Check preconditions -- */
786   assert(get_irn_op(call) == op_Call);
787   /* @@@ does not work for InterfaceIII.java after cgana
788      assert(get_Call_type(call) == get_entity_type(get_irg_entity(called_graph)));
789      assert(smaller_type(get_entity_type(get_irg_entity(called_graph)),
790      get_Call_type(call)));
791   */
792   assert(get_type_tpop(get_Call_type(call)) == type_method);
793   if (called_graph == current_ir_graph) {
794     set_optimize(rem_opt);
795     return 0;
796   }
797
798   /* here we know we WILL inline, so inform the statistics */
799   hook_inline(call, called_graph);
800
801   /* -- Decide how to handle exception control flow: Is there a handler
802      for the Call node, or do we branch directly to End on an exception?
803      exc_handling:
804      0 There is a handler.
805      1 Branches to End.
806      2 Exception handling not represented in Firm. -- */
807   {
808     ir_node *proj, *Mproj = NULL, *Xproj = NULL;
809     for (proj = (ir_node *)get_irn_link(call); proj; proj = (ir_node *)get_irn_link(proj)) {
810       assert(get_irn_op(proj) == op_Proj);
811       if (get_Proj_proj(proj) == pn_Call_X_except) Xproj = proj;
812       if (get_Proj_proj(proj) == pn_Call_M_except) Mproj = proj;
813     }
814     if      (Mproj) { assert(Xproj); exc_handling = 0; } /*  Mproj           */
815     else if (Xproj) {                exc_handling = 1; } /* !Mproj &&  Xproj   */
816     else            {                exc_handling = 2; } /* !Mproj && !Xproj   */
817   }
818
819
820   /* --
821      the procedure and later replaces the Start node of the called graph.
822      Post_call is the old Call node and collects the results of the called
823      graph. Both will end up being a tuple.  -- */
824   post_bl = get_nodes_block(call);
825   set_irg_current_block(current_ir_graph, post_bl);
826   /* XxMxPxP of Start + parameter of Call */
827   in[pn_Start_X_initial_exec] = new_Jmp();
828   in[pn_Start_M]              = get_Call_mem(call);
829   in[pn_Start_P_frame_base]   = get_irg_frame(current_ir_graph);
830   in[pn_Start_P_globals]      = get_irg_globals(current_ir_graph);
831   in[pn_Start_T_args]         = new_Tuple(get_Call_n_params(call), get_Call_param_arr(call));
832   /* in[pn_Start_P_value_arg_base] = ??? */
833   pre_call = new_Tuple(5, in);
834   post_call = call;
835
836   /* --
837      The new block gets the ins of the old block, pre_call and all its
838      predecessors and all Phi nodes. -- */
839   part_block(pre_call);
840
841   /* -- Prepare state for dead node elimination -- */
842   /* Visited flags in calling irg must be >= flag in called irg.
843      Else walker and arity computation will not work. */
844   if (get_irg_visited(current_ir_graph) <= get_irg_visited(called_graph))
845     set_irg_visited(current_ir_graph, get_irg_visited(called_graph)+1);
846   if (get_irg_block_visited(current_ir_graph)< get_irg_block_visited(called_graph))
847     set_irg_block_visited(current_ir_graph, get_irg_block_visited(called_graph));
848   /* Set pre_call as new Start node in link field of the start node of
849      calling graph and pre_calls block as new block for the start block
850      of calling graph.
851      Further mark these nodes so that they are not visited by the
852      copying. */
853   set_irn_link(get_irg_start(called_graph), pre_call);
854   set_irn_visited(get_irg_start(called_graph), get_irg_visited(current_ir_graph));
855   set_irn_link(get_irg_start_block(called_graph), get_nodes_block(pre_call));
856   set_irn_visited(get_irg_start_block(called_graph), get_irg_visited(current_ir_graph));
857   set_irn_link(get_irg_bad(called_graph), get_irg_bad(current_ir_graph));
858   set_irn_visited(get_irg_bad(called_graph), get_irg_visited(current_ir_graph));
859
860   /* Initialize for compaction of in arrays */
861   inc_irg_block_visited(current_ir_graph);
862
863   /* -- Replicate local entities of the called_graph -- */
864   /* copy the entities. */
865   called_frame = get_irg_frame_type(called_graph);
866   for (i = 0; i < get_class_n_members(called_frame); i++) {
867     entity *new_ent, *old_ent;
868     old_ent = get_class_member(called_frame, i);
869     new_ent = copy_entity_own(old_ent, get_cur_frame_type());
870     set_entity_link(old_ent, new_ent);
871   }
872
873   /* visited is > than that of called graph.  With this trick visited will
874      remain unchanged so that an outer walker, e.g., searching the call nodes
875      to inline, calling this inline will not visit the inlined nodes. */
876   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
877
878   /* -- Performing dead node elimination inlines the graph -- */
879   /* Copies the nodes to the obstack of current_ir_graph. Updates links to new
880      entities. */
881   /* @@@ endless loops are not copied!! -- they should be, I think... */
882   irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds,
883            get_irg_frame_type(called_graph));
884
885   /* Repair called_graph */
886   set_irg_visited(called_graph, get_irg_visited(current_ir_graph));
887   set_irg_block_visited(called_graph, get_irg_block_visited(current_ir_graph));
888   set_Block_block_visited(get_irg_start_block(called_graph), 0);
889
890   /* -- Merge the end of the inlined procedure with the call site -- */
891   /* We will turn the old Call node into a Tuple with the following
892      predecessors:
893      -1:  Block of Tuple.
894      0: Phi of all Memories of Return statements.
895      1: Jmp from new Block that merges the control flow from all exception
896      predecessors of the old end block.
897      2: Tuple of all arguments.
898      3: Phi of Exception memories.
899      In case the old Call directly branches to End on an exception we don't
900      need the block merging all exceptions nor the Phi of the exception
901      memories.
902   */
903
904   /* -- Precompute some values -- */
905   end_bl = get_new_node(get_irg_end_block(called_graph));
906   end = get_new_node(get_irg_end(called_graph));
907   arity = get_irn_arity(end_bl);    /* arity = n_exc + n_ret  */
908   n_res = get_method_n_ress(get_Call_type(call));
909
910   res_pred = xmalloc (n_res * sizeof(*res_pred));
911   cf_pred  = xmalloc (arity * sizeof(*res_pred));
912
913   set_irg_current_block(current_ir_graph, post_bl); /* just to make sure */
914
915   /* -- archive keepalives -- */
916   irn_arity = get_irn_arity(end);
917   for (i = 0; i < irn_arity; i++)
918     add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
919
920   /* The new end node will die.  We need not free as the in array is on the obstack:
921      copy_node() only generated 'D' arrays. */
922
923   /* -- Replace Return nodes by Jump nodes. -- */
924   n_ret = 0;
925   for (i = 0; i < arity; i++) {
926     ir_node *ret;
927     ret = get_irn_n(end_bl, i);
928     if (get_irn_op(ret) == op_Return) {
929       cf_pred[n_ret] = new_r_Jmp(current_ir_graph, get_nodes_block(ret));
930       n_ret++;
931     }
932   }
933   set_irn_in(post_bl, n_ret, cf_pred);
934
935   /* -- Build a Tuple for all results of the method.
936      Add Phi node if there was more than one Return.  -- */
937   turn_into_tuple(post_call, 4);
938   /* First the Memory-Phi */
939   n_ret = 0;
940   for (i = 0; i < arity; i++) {
941     ret = get_irn_n(end_bl, i);
942     if (get_irn_op(ret) == op_Return) {
943       cf_pred[n_ret] = get_Return_mem(ret);
944       n_ret++;
945     }
946   }
947   phi = new_Phi(n_ret, cf_pred, mode_M);
948   set_Tuple_pred(call, pn_Call_M_regular, phi);
949   /* Conserve Phi-list for further inlinings -- but might be optimized */
950   if (get_nodes_block(phi) == post_bl) {
951     set_irn_link(phi, get_irn_link(post_bl));
952     set_irn_link(post_bl, phi);
953   }
954   /* Now the real results */
955   if (n_res > 0) {
956     for (j = 0; j < n_res; j++) {
957       n_ret = 0;
958       for (i = 0; i < arity; i++) {
959         ret = get_irn_n(end_bl, i);
960         if (get_irn_op(ret) == op_Return) {
961           cf_pred[n_ret] = get_Return_res(ret, j);
962           n_ret++;
963         }
964       }
965       if (n_ret > 0)
966         phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0]));
967       else
968         phi = new_Bad();
969       res_pred[j] = phi;
970       /* Conserve Phi-list for further inlinings -- but might be optimized */
971       if (get_nodes_block(phi) == post_bl) {
972         set_irn_link(phi, get_irn_link(post_bl));
973         set_irn_link(post_bl, phi);
974       }
975     }
976     set_Tuple_pred(call, pn_Call_T_result, new_Tuple(n_res, res_pred));
977   } else {
978     set_Tuple_pred(call, pn_Call_T_result, new_Bad());
979   }
980   /* Finally the exception control flow.
981      We have two (three) possible situations:
982      First if the Call branches to an exception handler: We need to add a Phi node to
983      collect the memory containing the exception objects.  Further we need
984      to add another block to get a correct representation of this Phi.  To
985      this block we add a Jmp that resolves into the X output of the Call
986      when the Call is turned into a tuple.
987      Second the Call branches to End, the exception is not handled.  Just
988      add all inlined exception branches to the End node.
989      Third: there is no Exception edge at all. Handle as case two. */
990   if (exc_handling == 0) {
991     n_exc = 0;
992     for (i = 0; i < arity; i++) {
993       ir_node *ret;
994       ret = get_irn_n(end_bl, i);
995       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
996         cf_pred[n_exc] = ret;
997         n_exc++;
998       }
999     }
1000     if (n_exc > 0) {
1001       new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
1002       set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
1003       /* The Phi for the memories with the exception objects */
1004       n_exc = 0;
1005       for (i = 0; i < arity; i++) {
1006         ir_node *ret;
1007         ret = skip_Proj(get_irn_n(end_bl, i));
1008         if (get_irn_op(ret) == op_Call) {
1009           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 3);
1010           n_exc++;
1011         } else if (is_fragile_op(ret)) {
1012           /* We rely that all cfops have the memory output at the same position. */
1013           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 0);
1014           n_exc++;
1015         } else if (get_irn_op(ret) == op_Raise) {
1016           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 1);
1017           n_exc++;
1018         }
1019       }
1020       set_Tuple_pred(call, pn_Call_M_except, new_Phi(n_exc, cf_pred, mode_M));
1021     } else {
1022       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1023       set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1024     }
1025   } else {
1026     ir_node *main_end_bl;
1027     int main_end_bl_arity;
1028     ir_node **end_preds;
1029
1030     /* assert(exc_handling == 1 || no exceptions. ) */
1031     n_exc = 0;
1032     for (i = 0; i < arity; i++) {
1033       ir_node *ret = get_irn_n(end_bl, i);
1034
1035       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
1036         cf_pred[n_exc] = ret;
1037         n_exc++;
1038       }
1039     }
1040     main_end_bl = get_irg_end_block(current_ir_graph);
1041     main_end_bl_arity = get_irn_arity(main_end_bl);
1042     end_preds =  xmalloc ((n_exc + main_end_bl_arity) * sizeof(*end_preds));
1043
1044     for (i = 0; i < main_end_bl_arity; ++i)
1045       end_preds[i] = get_irn_n(main_end_bl, i);
1046     for (i = 0; i < n_exc; ++i)
1047       end_preds[main_end_bl_arity + i] = cf_pred[i];
1048     set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
1049     set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1050     set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1051     free(end_preds);
1052   }
1053   free(res_pred);
1054   free(cf_pred);
1055
1056 #if 0  /* old. now better, correcter, faster implementation. */
1057   if (n_exc > 0) {
1058     /* -- If the exception control flow from the inlined Call directly
1059        branched to the end block we now have the following control
1060        flow predecessor pattern: ProjX -> Tuple -> Jmp.  We must
1061        remove the Jmp along with it's empty block and add Jmp's
1062        predecessors as predecessors of this end block.  No problem if
1063        there is no exception, because then branches Bad to End which
1064        is fine. --
1065        @@@ can't we know this beforehand: by getting the Proj(1) from
1066        the Call link list and checking whether it goes to Proj. */
1067     /* find the problematic predecessor of the end block. */
1068     end_bl = get_irg_end_block(current_ir_graph);
1069     for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
1070       cf_op = get_Block_cfgpred(end_bl, i);
1071       if (get_irn_op(cf_op) == op_Proj) {
1072         cf_op = get_Proj_pred(cf_op);
1073         if ((get_irn_op(cf_op) == op_Tuple) && (cf_op == call)) {
1074           /*  There are unoptimized tuples from inlineing before when no exc */
1075           assert(get_Proj_proj(get_Block_cfgpred(end_bl, i)) == pn_Call_X_except);
1076           cf_op = get_Tuple_pred(cf_op, pn_Call_X_except);
1077           assert(get_irn_op(cf_op) == op_Jmp);
1078           break;
1079         }
1080       }
1081     }
1082     /* repair */
1083     if (i < get_Block_n_cfgpreds(end_bl)) {
1084       bl = get_nodes_block(cf_op);
1085       arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
1086       cf_pred = xmalloc (arity * sizeof(*cf_pred));
1087       for (j = 0; j < i; j++)
1088         cf_pred[j] = get_Block_cfgpred(end_bl, j);
1089       for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
1090         cf_pred[j] = get_Block_cfgpred(bl, j-i);
1091       for (j = j; j < arity; j++)
1092         cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
1093       set_irn_in(end_bl, arity, cf_pred);
1094       free(cf_pred);
1095       /*  Remove the exception pred from post-call Tuple. */
1096       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1097     }
1098   }
1099 #endif
1100
1101   /* --  Turn CSE back on. -- */
1102   set_optimize(rem_opt);
1103
1104   return 1;
1105 }
1106
1107 /********************************************************************/
1108 /* Apply inlineing to small methods.                                */
1109 /********************************************************************/
1110
1111 /* It makes no sense to inline too many calls in one procedure. Anyways,
1112    I didn't get a version with NEW_ARR_F to run. */
1113 #define MAX_INLINE 1024
1114
1115 /**
1116  * environment for inlining small irgs
1117  */
1118 typedef struct _inline_env_t {
1119   int pos;
1120   ir_node *calls[MAX_INLINE];
1121 } inline_env_t;
1122
1123 /**
1124  * Returns the irg called from a Call node. If the irg is not
1125  * known, NULL is returned.
1126  */
1127 static ir_graph *get_call_called_irg(ir_node *call) {
1128   ir_node *addr;
1129   ir_graph *called_irg = NULL;
1130
1131   assert(get_irn_op(call) == op_Call);
1132
1133   addr = get_Call_ptr(call);
1134   if ((get_irn_op(addr) == op_SymConst) && (get_SymConst_kind (addr) == symconst_addr_ent)) {
1135     called_irg = get_entity_irg(get_SymConst_entity(addr));
1136   }
1137
1138   return called_irg;
1139 }
1140
1141 static void collect_calls(ir_node *call, void *env) {
1142   ir_node *addr;
1143
1144   if (get_irn_op(call) != op_Call) return;
1145
1146   addr = get_Call_ptr(call);
1147
1148   if (get_irn_op(addr) == op_SymConst) {
1149     if (get_SymConst_kind(addr) == symconst_addr_ent) {
1150       ir_graph *called_irg = get_entity_irg(get_SymConst_entity(addr));
1151       inline_env_t *ienv = (inline_env_t *)env;
1152       if (called_irg && ienv->pos < MAX_INLINE) {
1153         /* The Call node calls a locally defined method.  Remember to inline. */
1154         ienv->calls[ienv->pos++] = call;
1155       }
1156     }
1157   }
1158 }
1159
1160 /**
1161  * Inlines all small methods at call sites where the called address comes
1162  * from a Const node that references the entity representing the called
1163  * method.
1164  * The size argument is a rough measure for the code size of the method:
1165  * Methods where the obstack containing the firm graph is smaller than
1166  * size are inlined.
1167  */
1168 void inline_small_irgs(ir_graph *irg, int size) {
1169   int i;
1170   ir_graph *rem = current_ir_graph;
1171   inline_env_t env /* = {0, NULL}*/;
1172
1173   if (!(get_opt_optimize() && get_opt_inline())) return;
1174
1175   current_ir_graph = irg;
1176   /* Handle graph state */
1177   assert(get_irg_phase_state(current_ir_graph) != phase_building);
1178   free_callee_info(current_ir_graph);
1179
1180   /* Find Call nodes to inline.
1181      (We can not inline during a walk of the graph, as inlineing the same
1182      method several times changes the visited flag of the walked graph:
1183      after the first inlineing visited of the callee equals visited of
1184      the caller.  With the next inlineing both are increased.) */
1185   env.pos = 0;
1186   irg_walk(get_irg_end(irg), NULL, collect_calls, &env);
1187
1188   if ((env.pos > 0) && (env.pos < MAX_INLINE)) {
1189     /* There are calls to inline */
1190     collect_phiprojs(irg);
1191     for (i = 0; i < env.pos; i++) {
1192       ir_graph *callee;
1193       callee = get_entity_irg(get_SymConst_entity(get_Call_ptr(env.calls[i])));
1194       if (((_obstack_memory_used(callee->obst) - (int)obstack_room(callee->obst)) < size) ||
1195         (get_irg_inline_property(callee) == irg_inline_forced)) {
1196         inline_method(env.calls[i], callee);
1197       }
1198     }
1199   }
1200
1201   current_ir_graph = rem;
1202 }
1203
1204 /**
1205  * Environment for inlining irgs.
1206  */
1207 typedef struct {
1208   int n_nodes;       /**< Nodes in graph except Id, Tuple, Proj, Start, End */
1209   int n_nodes_orig;  /**< for statistics */
1210   eset *call_nodes;  /**< All call nodes in this graph */
1211   int n_call_nodes;
1212   int n_call_nodes_orig; /**< for statistics */
1213   int n_callers;   /**< Number of known graphs that call this graphs. */
1214   int n_callers_orig; /**< for statistics */
1215 } inline_irg_env;
1216
1217 /**
1218  * Allocate a new environment for inlining.
1219  */
1220 static inline_irg_env *new_inline_irg_env(void) {
1221   inline_irg_env *env    = xmalloc(sizeof(*env));
1222   env->n_nodes           = -2; /* do not count count Start, End */
1223   env->n_nodes_orig      = -2; /* do not count Start, End */
1224   env->call_nodes        = eset_create();
1225   env->n_call_nodes      = 0;
1226   env->n_call_nodes_orig = 0;
1227   env->n_callers         = 0;
1228   env->n_callers_orig    = 0;
1229   return env;
1230 }
1231
1232 /**
1233  * destroy an environment for inlining.
1234  */
1235 static void free_inline_irg_env(inline_irg_env *env) {
1236   eset_destroy(env->call_nodes);
1237   free(env);
1238 }
1239
1240 /**
1241  * post-walker: collect all calls in the inline-environment
1242  * of a graph and sum some statistics.
1243  */
1244 static void collect_calls2(ir_node *call, void *env) {
1245   inline_irg_env *x = (inline_irg_env *)env;
1246   ir_op *op = get_irn_op(call);
1247   ir_graph *callee;
1248
1249   /* count meaningful nodes in irg */
1250   if (op != op_Proj && op != op_Tuple && op != op_Sync) {
1251     x->n_nodes++;
1252     x->n_nodes_orig++;
1253   }
1254
1255   if (op != op_Call) return;
1256
1257   /* collect all call nodes */
1258   eset_insert(x->call_nodes, call);
1259   x->n_call_nodes++;
1260   x->n_call_nodes_orig++;
1261
1262   /* count all static callers */
1263   callee = get_call_called_irg(call);
1264   if (callee) {
1265     inline_irg_env *callee_env = get_irg_link(callee);
1266     callee_env->n_callers++;
1267     callee_env->n_callers_orig++;
1268   }
1269 }
1270
1271 /**
1272  * Returns TRUE if the number of callers in 0 in the irg's environment,
1273  * hence this irg is a leave.
1274  */
1275 INLINE static int is_leave(ir_graph *irg) {
1276   return (((inline_irg_env *)get_irg_link(irg))->n_call_nodes == 0);
1277 }
1278
1279 /**
1280  * Returns TRUE if the number of callers is smaller size in the irg's environment.
1281  */
1282 INLINE static int is_smaller(ir_graph *callee, int size) {
1283   return (((inline_irg_env *)get_irg_link(callee))->n_nodes < size);
1284 }
1285
1286
1287 /*
1288  * Inlines small leave methods at call sites where the called address comes
1289  * from a Const node that references the entity representing the called
1290  * method.
1291  * The size argument is a rough measure for the code size of the method:
1292  * Methods where the obstack containing the firm graph is smaller than
1293  * size are inlined.
1294  */
1295 void inline_leave_functions(int maxsize, int leavesize, int size) {
1296   inline_irg_env *env;
1297   int i, n_irgs = get_irp_n_irgs();
1298   ir_graph *rem = current_ir_graph;
1299   int did_inline = 1;
1300
1301   if (!(get_opt_optimize() && get_opt_inline())) return;
1302
1303   /* extend all irgs by a temporary data structure for inlining. */
1304   for (i = 0; i < n_irgs; ++i)
1305     set_irg_link(get_irp_irg(i), new_inline_irg_env());
1306
1307   /* Precompute information in temporary data structure. */
1308   for (i = 0; i < n_irgs; ++i) {
1309     current_ir_graph = get_irp_irg(i);
1310     assert(get_irg_phase_state(current_ir_graph) != phase_building);
1311     free_callee_info(current_ir_graph);
1312
1313     irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2,
1314              get_irg_link(current_ir_graph));
1315   }
1316
1317   /* -- and now inline. -- */
1318
1319   /* Inline leaves recursively -- we might construct new leaves. */
1320   while (did_inline) {
1321     did_inline = 0;
1322
1323     for (i = 0; i < n_irgs; ++i) {
1324       ir_node *call;
1325       int phiproj_computed = 0;
1326
1327       current_ir_graph = get_irp_irg(i);
1328       env = (inline_irg_env *)get_irg_link(current_ir_graph);
1329
1330       for (call = eset_first(env->call_nodes); call; call = eset_next(env->call_nodes)) {
1331         ir_graph *callee;
1332
1333         if (get_irn_op(call) == op_Tuple) continue;   /* We already have inlined this call. */
1334         callee = get_call_called_irg(call);
1335
1336         if (env->n_nodes > maxsize) continue; // break;
1337
1338         if (callee && (is_leave(callee) && is_smaller(callee, leavesize))) {
1339           if (!phiproj_computed) {
1340             phiproj_computed = 1;
1341             collect_phiprojs(current_ir_graph);
1342           }
1343           did_inline = inline_method(call, callee);
1344
1345           if (did_inline) {
1346             /* Do some statistics */
1347             inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1348             env->n_call_nodes --;
1349             env->n_nodes += callee_env->n_nodes;
1350             callee_env->n_callers--;
1351           }
1352         }
1353       }
1354     }
1355   }
1356
1357   /* inline other small functions. */
1358   for (i = 0; i < n_irgs; ++i) {
1359     ir_node *call;
1360     eset *walkset;
1361     int phiproj_computed = 0;
1362
1363     current_ir_graph = get_irp_irg(i);
1364     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1365
1366     /* we can not walk and change a set, nor remove from it.
1367        So recompute.*/
1368     walkset = env->call_nodes;
1369     env->call_nodes = eset_create();
1370     for (call = eset_first(walkset); call; call = eset_next(walkset)) {
1371       ir_graph *callee;
1372
1373       if (get_irn_op(call) == op_Tuple) continue;   /* We already inlined. */
1374       callee = get_call_called_irg(call);
1375
1376       if (callee &&
1377           ((is_smaller(callee, size) && (env->n_nodes < maxsize)) ||    /* small function */
1378            (get_irg_inline_property(callee) == irg_inline_forced))) {
1379         if (!phiproj_computed) {
1380             phiproj_computed = 1;
1381             collect_phiprojs(current_ir_graph);
1382         }
1383         if (inline_method(call, callee)) {
1384           inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1385           env->n_call_nodes--;
1386           eset_insert_all(env->call_nodes, callee_env->call_nodes);  /* @@@ ??? This are the wrong nodes !? Not the copied ones. */
1387           env->n_call_nodes += callee_env->n_call_nodes;
1388           env->n_nodes += callee_env->n_nodes;
1389           callee_env->n_callers--;
1390         }
1391       } else {
1392         eset_insert(env->call_nodes, call);
1393       }
1394     }
1395     eset_destroy(walkset);
1396   }
1397
1398   for (i = 0; i < n_irgs; ++i) {
1399     current_ir_graph = get_irp_irg(i);
1400 #if 0
1401     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1402     if ((env->n_call_nodes_orig != env->n_call_nodes) ||
1403         (env->n_callers_orig != env->n_callers))
1404       printf("Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
1405              env->n_nodes_orig, env->n_nodes, env->n_call_nodes_orig, env->n_call_nodes,
1406              env->n_callers_orig, env->n_callers,
1407              get_entity_name(get_irg_entity(current_ir_graph)));
1408 #endif
1409     free_inline_irg_env((inline_irg_env *)get_irg_link(current_ir_graph));
1410   }
1411
1412   current_ir_graph = rem;
1413 }
1414
1415 /*******************************************************************/
1416 /*  Code Placement.  Pins all floating nodes to a block where they */
1417 /*  will be executed only if needed.                               */
1418 /*******************************************************************/
1419
1420 /**
1421  * Returns non-zero, is a block is not reachable from Start.
1422  *
1423  * @param block  the block to test
1424  */
1425 static int
1426 is_Block_unreachable(ir_node *block) {
1427   return is_Block_dead(block) || get_Block_dom_depth(block) < 0;
1428 }
1429
1430 /**
1431  * Find the earliest correct block for N.  --- Place N into the
1432  * same Block as its dominance-deepest Input.
1433  *
1434  * We have to avoid calls to get_nodes_block() here
1435  * because the graph is floating.
1436  *
1437  * move_out_of_loops() expects that place_floats_early() have placed
1438  * all "living" nodes into a living block. That's why we must
1439  * move nodes in dead block with "live" successors into a valid
1440  * block.
1441  * We move them just into the same block as it's successor (or
1442  * in case of a Phi into the effective use block). For Phi successors,
1443  * this may still be a dead block, but then there is no real use, as
1444  * the control flow will be dead later.
1445  */
1446 static void
1447 place_floats_early(ir_node *n, pdeq *worklist)
1448 {
1449   int i, irn_arity;
1450
1451   /* we must not run into an infinite loop */
1452   assert(irn_not_visited(n));
1453   mark_irn_visited(n);
1454
1455   /* Place floating nodes. */
1456   if (get_irn_pinned(n) == op_pin_state_floats) {
1457     ir_node *curr_block = get_irn_n(n, -1);
1458     int in_dead_block   = is_Block_unreachable(curr_block);
1459     int depth           = 0;
1460     ir_node *b          = NULL;   /* The block to place this node in */
1461
1462     assert(get_irn_op(n) != op_Block);
1463
1464     if ((get_irn_op(n) == op_Const) ||
1465         (get_irn_op(n) == op_SymConst) ||
1466         (is_Bad(n)) ||
1467         (get_irn_op(n) == op_Unknown)) {
1468       /* These nodes will not be placed by the loop below. */
1469       b = get_irg_start_block(current_ir_graph);
1470       depth = 1;
1471     }
1472
1473     /* find the block for this node. */
1474     irn_arity = get_irn_arity(n);
1475     for (i = 0; i < irn_arity; i++) {
1476       ir_node *pred = get_irn_n(n, i);
1477       ir_node *pred_block;
1478
1479       if ((irn_not_visited(pred))
1480          && (get_irn_pinned(pred) == op_pin_state_floats)) {
1481
1482         /*
1483          * If the current node is NOT in a dead block, but one of its
1484          * predecessors is, we must move the predecessor to a live block.
1485          * Such thing can happen, if global CSE chose a node from a dead block.
1486          * We move it simple to our block.
1487          * Note that neither Phi nor End nodes are floating, so we don't
1488          * need to handle them here.
1489          */
1490         if (! in_dead_block) {
1491           if (get_irn_pinned(pred) == op_pin_state_floats &&
1492               is_Block_unreachable(get_irn_n(pred, -1)))
1493             set_nodes_block(pred, curr_block);
1494         }
1495         place_floats_early(pred, worklist);
1496       }
1497
1498       /*
1499        * A node in the Bad block must stay in the bad block,
1500        * so don't compute a new block for it.
1501        */
1502       if (in_dead_block)
1503         continue;
1504
1505       /* Because all loops contain at least one op_pin_state_pinned node, now all
1506          our inputs are either op_pin_state_pinned or place_early() has already
1507          been finished on them.  We do not have any unfinished inputs!  */
1508       pred_block = get_irn_n(pred, -1);
1509       if ((!is_Block_dead(pred_block)) &&
1510           (get_Block_dom_depth(pred_block) > depth)) {
1511         b = pred_block;
1512         depth = get_Block_dom_depth(pred_block);
1513       }
1514       /* Avoid that the node is placed in the Start block */
1515       if ((depth == 1) && (get_Block_dom_depth(get_irn_n(n, -1)) > 1)) {
1516         b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
1517         assert(b != get_irg_start_block(current_ir_graph));
1518         depth = 2;
1519       }
1520     }
1521     if (b)
1522       set_nodes_block(n, b);
1523   }
1524
1525   /*
1526    * Add predecessors of non floating nodes and non-floating predecessors
1527    * of floating nodes to worklist and fix their blocks if the are in dead block.
1528    */
1529   irn_arity = get_irn_arity(n);
1530
1531   if (get_irn_op(n) == op_End) {
1532     /*
1533      * Simplest case: End node. Predecessors are keep-alives,
1534      * no need to move out of dead block.
1535      */
1536     for (i = -1; i < irn_arity; ++i) {
1537       ir_node *pred = get_irn_n(n, i);
1538       if (irn_not_visited(pred))
1539         pdeq_putr(worklist, pred);
1540     }
1541   }
1542   else if (is_Block(n)) {
1543     /*
1544      * Blocks: Predecessors are control flow, no need to move
1545      * them out of dead block.
1546      */
1547     for (i = irn_arity - 1; i >= 0; --i) {
1548       ir_node *pred = get_irn_n(n, i);
1549       if (irn_not_visited(pred))
1550         pdeq_putr(worklist, pred);
1551     }
1552   }
1553   else if (is_Phi(n)) {
1554     ir_node *pred;
1555     ir_node *curr_block = get_irn_n(n, -1);
1556     int in_dead_block   = is_Block_unreachable(curr_block);
1557
1558     /*
1559      * Phi nodes: move nodes from dead blocks into the effective use
1560      * of the Phi-input if the Phi is not in a bad block.
1561      */
1562     pred = get_irn_n(n, -1);
1563     if (irn_not_visited(pred))
1564       pdeq_putr(worklist, pred);
1565
1566     for (i = irn_arity - 1; i >= 0; --i) {
1567       ir_node *pred = get_irn_n(n, i);
1568
1569       if (irn_not_visited(pred)) {
1570         if (! in_dead_block &&
1571             get_irn_pinned(pred) == op_pin_state_floats &&
1572             is_Block_unreachable(get_irn_n(pred, -1))) {
1573           set_nodes_block(pred, get_Block_cfgpred_block(curr_block, i));
1574         }
1575         pdeq_putr(worklist, pred);
1576       }
1577     }
1578   }
1579   else {
1580     ir_node *pred;
1581     ir_node *curr_block = get_irn_n(n, -1);
1582     int in_dead_block   = is_Block_unreachable(curr_block);
1583
1584     /*
1585      * All other nodes: move nodes from dead blocks into the same block.
1586      */
1587     pred = get_irn_n(n, -1);
1588     if (irn_not_visited(pred))
1589       pdeq_putr(worklist, pred);
1590
1591     for (i = irn_arity - 1; i >= 0; --i) {
1592       ir_node *pred = get_irn_n(n, i);
1593
1594       if (irn_not_visited(pred)) {
1595         if (! in_dead_block &&
1596             get_irn_pinned(pred) == op_pin_state_floats &&
1597             is_Block_unreachable(get_irn_n(pred, -1))) {
1598           set_nodes_block(pred, curr_block);
1599         }
1600         pdeq_putr(worklist, pred);
1601       }
1602     }
1603   }
1604 }
1605
1606 /**
1607  * Floating nodes form subgraphs that begin at nodes as Const, Load,
1608  * Start, Call and that end at op_pin_state_pinned nodes as Store, Call.  Place_early
1609  * places all floating nodes reachable from its argument through floating
1610  * nodes and adds all beginnings at op_pin_state_pinned nodes to the worklist.
1611  */
1612 static INLINE void place_early(pdeq *worklist) {
1613   assert(worklist);
1614   inc_irg_visited(current_ir_graph);
1615
1616   /* this inits the worklist */
1617   place_floats_early(get_irg_end(current_ir_graph), worklist);
1618
1619   /* Work the content of the worklist. */
1620   while (!pdeq_empty(worklist)) {
1621     ir_node *n = pdeq_getl(worklist);
1622     if (irn_not_visited(n))
1623       place_floats_early(n, worklist);
1624   }
1625
1626   set_irg_outs_inconsistent(current_ir_graph);
1627   set_irg_pinned(current_ir_graph, op_pin_state_pinned);
1628 }
1629
1630 /**
1631  * Compute the deepest common ancestor of block and dca.
1632  */
1633 static ir_node *calc_dca(ir_node *dca, ir_node *block)
1634 {
1635   assert(block);
1636
1637   /* we do not want to place nodes in dead blocks */
1638   if (is_Block_dead(block))
1639     return dca;
1640
1641   /* We found a first legal placement. */
1642   if (!dca) return block;
1643
1644   /* Find a placement that is dominates both, dca and block. */
1645   while (get_Block_dom_depth(block) > get_Block_dom_depth(dca))
1646     block = get_Block_idom(block);
1647
1648   while (get_Block_dom_depth(dca) > get_Block_dom_depth(block)) {
1649     dca = get_Block_idom(dca);
1650   }
1651
1652   while (block != dca)
1653     { block = get_Block_idom(block); dca = get_Block_idom(dca); }
1654
1655   return dca;
1656 }
1657
1658 /** Deepest common dominance ancestor of DCA and CONSUMER of PRODUCER.
1659  * I.e., DCA is the block where we might place PRODUCER.
1660  * A data flow edge points from producer to consumer.
1661  */
1662 static ir_node *
1663 consumer_dom_dca(ir_node *dca, ir_node *consumer, ir_node *producer)
1664 {
1665   ir_node *block = NULL;
1666
1667   /* Compute the latest block into which we can place a node so that it is
1668      before consumer. */
1669   if (get_irn_op(consumer) == op_Phi) {
1670     /* our consumer is a Phi-node, the effective use is in all those
1671        blocks through which the Phi-node reaches producer */
1672     int i, irn_arity;
1673     ir_node *phi_block = get_nodes_block(consumer);
1674     irn_arity = get_irn_arity(consumer);
1675
1676     for (i = 0;  i < irn_arity; i++) {
1677       if (get_irn_n(consumer, i) == producer) {
1678         ir_node *new_block = get_nodes_block(get_Block_cfgpred(phi_block, i));
1679
1680         if (! is_Block_unreachable(new_block))
1681           block = calc_dca(block, new_block);
1682       }
1683     }
1684
1685     if (! block)
1686       block = get_irn_n(producer, -1);
1687   }
1688   else {
1689     assert(is_no_Block(consumer));
1690     block = get_nodes_block(consumer);
1691   }
1692
1693   /* Compute the deepest common ancestor of block and dca. */
1694   return calc_dca(dca, block);
1695 }
1696
1697 /* FIXME: the name clashes here with the function from ana/field_temperature.c
1698  * please rename. */
1699 static INLINE int get_irn_loop_depth(ir_node *n) {
1700   return get_loop_depth(get_irn_loop(n));
1701 }
1702
1703 /**
1704  * Move n to a block with less loop depth than it's current block. The
1705  * new block must be dominated by early.
1706  *
1707  * @param n      the node that should be moved
1708  * @param early  the earliest block we can n move to
1709  */
1710 static void
1711 move_out_of_loops (ir_node *n, ir_node *early)
1712 {
1713   ir_node *best, *dca;
1714   assert(n && early);
1715
1716
1717   /* Find the region deepest in the dominator tree dominating
1718      dca with the least loop nesting depth, but still dominated
1719      by our early placement. */
1720   dca = get_nodes_block(n);
1721
1722   best = dca;
1723   while (dca != early) {
1724     dca = get_Block_idom(dca);
1725     if (!dca || is_Bad(dca)) break; /* may be Bad if not reachable from Start */
1726     if (get_irn_loop_depth(dca) < get_irn_loop_depth(best)) {
1727       best = dca;
1728     }
1729   }
1730   if (best != get_nodes_block(n)) {
1731     /* debug output
1732     printf("Moving out of loop: "); DDMN(n);
1733     printf(" Outermost block: "); DDMN(early);
1734     printf(" Best block: "); DDMN(best);
1735     printf(" Innermost block: "); DDMN(get_nodes_block(n));
1736     */
1737     set_nodes_block(n, best);
1738   }
1739 }
1740
1741 /**
1742  * Find the latest legal block for N and place N into the
1743  * `optimal' Block between the latest and earliest legal block.
1744  * The `optimal' block is the dominance-deepest block of those
1745  * with the least loop-nesting-depth.  This places N out of as many
1746  * loops as possible and then makes it as control dependent as
1747  * possible.
1748  */
1749 static void
1750 place_floats_late(ir_node *n, pdeq *worklist)
1751 {
1752   int i;
1753   ir_node *early_blk;
1754
1755   assert(irn_not_visited(n)); /* no multiple placement */
1756
1757   mark_irn_visited(n);
1758
1759   /* no need to place block nodes, control nodes are already placed. */
1760   if ((get_irn_op(n) != op_Block) &&
1761       (!is_cfop(n)) &&
1762       (get_irn_mode(n) != mode_X)) {
1763     /* Remember the early_blk placement of this block to move it
1764        out of loop no further than the early_blk placement. */
1765     early_blk = get_irn_n(n, -1);
1766
1767     /*
1768      * BEWARE: Here we also get code, that is live, but
1769      * was in a dead block.  If the node is life, but because
1770      * of CSE in a dead block, we still might need it.
1771      */
1772
1773     /* Assure that our users are all placed, except the Phi-nodes.
1774        --- Each data flow cycle contains at least one Phi-node.  We
1775        have to break the `user has to be placed before the
1776        producer' dependence cycle and the Phi-nodes are the
1777        place to do so, because we need to base our placement on the
1778        final region of our users, which is OK with Phi-nodes, as they
1779        are op_pin_state_pinned, and they never have to be placed after a
1780        producer of one of their inputs in the same block anyway. */
1781     for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
1782       ir_node *succ = get_irn_out(n, i);
1783       if (irn_not_visited(succ) && (get_irn_op(succ) != op_Phi))
1784         place_floats_late(succ, worklist);
1785     }
1786
1787     if (! is_Block_dead(early_blk)) {
1788       /* do only move things that where not dead */
1789
1790       /* We have to determine the final block of this node... except for
1791          constants. */
1792       if ((get_irn_pinned(n) == op_pin_state_floats) &&
1793           (get_irn_op(n) != op_Const) &&
1794           (get_irn_op(n) != op_SymConst)) {
1795         ir_node *dca = NULL;  /* deepest common ancestor in the
1796                      dominator tree of all nodes'
1797                      blocks depending on us; our final
1798                      placement has to dominate DCA. */
1799         for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
1800           ir_node *succ = get_irn_out(n, i);
1801           ir_node *succ_blk;
1802
1803           if (get_irn_op(succ) == op_End) {
1804             /*
1805              * This consumer is the End node, a keep alive edge.
1806              * This is not a real consumer, so we ignore it
1807              */
1808             continue;
1809           }
1810
1811           /* ignore if succ is in dead code */
1812           succ_blk = get_irn_n(succ, -1);
1813           if (is_Block_unreachable(succ_blk))
1814             continue;
1815           dca = consumer_dom_dca(dca, succ, n);
1816         }
1817         if (dca) {
1818           set_nodes_block(n, dca);
1819           move_out_of_loops(n, early_blk);
1820         }
1821       }
1822     }
1823   }
1824
1825   /* Add predecessors of all non-floating nodes on list. (Those of floating
1826      nodes are placed already and therefore are marked.)  */
1827   for (i = 0; i < get_irn_n_outs(n); i++) {
1828     ir_node *succ = get_irn_out(n, i);
1829     if (irn_not_visited(get_irn_out(n, i))) {
1830       pdeq_putr(worklist, succ);
1831     }
1832   }
1833 }
1834
1835 static INLINE void place_late(pdeq *worklist) {
1836   assert(worklist);
1837   inc_irg_visited(current_ir_graph);
1838
1839   /* This fills the worklist initially. */
1840   place_floats_late(get_irg_start_block(current_ir_graph), worklist);
1841
1842   /* And now empty the worklist again... */
1843   while (!pdeq_empty(worklist)) {
1844     ir_node *n = pdeq_getl(worklist);
1845     if (irn_not_visited(n))
1846       place_floats_late(n, worklist);
1847   }
1848 }
1849
1850 void place_code(ir_graph *irg) {
1851   pdeq *worklist;
1852   ir_graph *rem = current_ir_graph;
1853
1854   current_ir_graph = irg;
1855
1856   if (!(get_opt_optimize() && get_opt_global_cse())) return;
1857
1858   /* Handle graph state */
1859   assert(get_irg_phase_state(irg) != phase_building);
1860   if (get_irg_dom_state(irg) != dom_consistent)
1861     compute_doms(irg);
1862
1863   if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) {
1864     free_loop_information(irg);
1865     construct_backedges(irg);
1866   }
1867
1868   /* Place all floating nodes as early as possible. This guarantees
1869      a legal code placement. */
1870   worklist = new_pdeq();
1871   place_early(worklist);
1872
1873   /* place_early() invalidates the outs, place_late needs them. */
1874   compute_irg_outs(irg);
1875
1876   /* Now move the nodes down in the dominator tree. This reduces the
1877      unnecessary executions of the node. */
1878   place_late(worklist);
1879
1880   set_irg_outs_inconsistent(current_ir_graph);
1881   set_irg_loopinfo_inconsistent(current_ir_graph);
1882   del_pdeq(worklist);
1883   current_ir_graph = rem;
1884 }
1885
1886 /**
1887  * Called by walker of remove_critical_cf_edges().
1888  *
1889  * Place an empty block to an edge between a blocks of multiple
1890  * predecessors and a block of multiple successors.
1891  *
1892  * @param n IR node
1893  * @param env Environment of walker. This field is unused and has
1894  *            the value NULL.
1895  */
1896 static void walk_critical_cf_edges(ir_node *n, void *env) {
1897   int arity, i;
1898   ir_node *pre, *block, **in, *jmp;
1899
1900   /* Block has multiple predecessors */
1901   if ((op_Block == get_irn_op(n)) &&
1902       (get_irn_arity(n) > 1)) {
1903     arity = get_irn_arity(n);
1904
1905     if (n == get_irg_end_block(current_ir_graph))
1906       return;  /*  No use to add a block here.      */
1907
1908     for (i=0; i<arity; i++) {
1909       pre = get_irn_n(n, i);
1910       /* Predecessor has multiple successors. Insert new flow edge */
1911       if ((NULL != pre) &&
1912     (op_Proj == get_irn_op(pre)) &&
1913     op_Raise != get_irn_op(skip_Proj(pre))) {
1914
1915     /* set predecessor array for new block */
1916     in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 1);
1917     /* set predecessor of new block */
1918     in[0] = pre;
1919     block = new_Block(1, in);
1920     /* insert new jmp node to new block */
1921     set_cur_block(block);
1922     jmp = new_Jmp();
1923     set_cur_block(n);
1924     /* set successor of new block */
1925     set_irn_n(n, i, jmp);
1926
1927       } /* predecessor has multiple successors */
1928     } /* for all predecessors */
1929   } /* n is a block */
1930 }
1931
1932 void remove_critical_cf_edges(ir_graph *irg) {
1933   if (get_opt_critical_edges())
1934     irg_walk_graph(irg, NULL, walk_critical_cf_edges, NULL);
1935 }