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