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