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