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