7786366277623410f04ceb49f7e512c287147e22
[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(irg, 1);
526
527   /* Remember external state of current_ir_graph. */
528   rem = current_ir_graph;
529   current_ir_graph = irg;
530   set_interprocedural_view(0);
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(irg, 0);
565
566   current_ir_graph = rem;
567   set_interprocedural_view(rem_ipview);
568
569         /* reset the dominator's state */
570         if(get_irg_dom_state(irg) != dom_none)
571                 set_irg_dom_inconsistent(irg);
572 }
573
574 /**
575  * Relink bad predecessors of a block and store the old in array to the
576  * link field. This function is called by relink_bad_predecessors().
577  * The array of link field starts with the block operand at position 0.
578  * If block has bad predecessors, create a new in array without bad preds.
579  * Otherwise let in array untouched.
580  */
581 static void relink_bad_block_predecessors(ir_node *n, void *env) {
582   ir_node **new_in, *irn;
583   int i, new_irn_n, old_irn_arity, new_irn_arity = 0;
584
585   /* if link field of block is NULL, look for bad predecessors otherwise
586      this is already done */
587   if (get_irn_op(n) == op_Block &&
588       get_irn_link(n) == NULL) {
589
590     /* save old predecessors in link field (position 0 is the block operand)*/
591     set_irn_link(n, get_irn_in(n));
592
593     /* count predecessors without bad nodes */
594     old_irn_arity = get_irn_arity(n);
595     for (i = 0; i < old_irn_arity; i++)
596       if (!is_Bad(get_irn_n(n, i))) new_irn_arity++;
597
598     /* arity changing: set new predecessors without bad nodes */
599     if (new_irn_arity < old_irn_arity) {
600       /* Get new predecessor array. We do not resize the array, as we must
601          keep the old one to update Phis. */
602       new_in = NEW_ARR_D (ir_node *, current_ir_graph->obst, (new_irn_arity+1));
603
604       /* set new predecessors in array */
605       new_in[0] = NULL;
606       new_irn_n = 1;
607       for (i = 0; i < old_irn_arity; i++) {
608         irn = get_irn_n(n, i);
609         if (!is_Bad(irn)) {
610           new_in[new_irn_n] = irn;
611           is_backedge(n, i) ? set_backedge(n, new_irn_n-1) : set_not_backedge(n, new_irn_n-1);
612           ++new_irn_n;
613         }
614       }
615       //ARR_SETLEN(int, n->attr.block.backedge, new_irn_arity);
616       ARR_SHRINKLEN(n->attr.block.backedge, new_irn_arity);
617       n->in = new_in;
618
619     } /* ir node has bad predecessors */
620
621   } /* Block is not relinked */
622 }
623
624 /**
625  * Relinks Bad predecessors from Blocks and Phis called by walker
626  * remove_bad_predecesors(). If n is a Block, call
627  * relink_bad_block_redecessors(). If n is a Phi-node, call also the relinking
628  * function of Phi's Block. If this block has bad predecessors, relink preds
629  * of the Phi-node.
630  */
631 static void relink_bad_predecessors(ir_node *n, void *env) {
632   ir_node *block, **old_in;
633   int i, old_irn_arity, new_irn_arity;
634
635   /* relink bad predecessors of a block */
636   if (get_irn_op(n) == op_Block)
637     relink_bad_block_predecessors(n, env);
638
639   /* If Phi node relink its block and its predecessors */
640   if (get_irn_op(n) == op_Phi) {
641
642     /* Relink predecessors of phi's block */
643     block = get_nodes_block(n);
644     if (get_irn_link(block) == NULL)
645       relink_bad_block_predecessors(block, env);
646
647     old_in = (ir_node **)get_irn_link(block); /* Of Phi's Block */
648     old_irn_arity = ARR_LEN(old_in);
649
650     /* Relink Phi predecessors if count of predecessors changed */
651     if (old_irn_arity != ARR_LEN(get_irn_in(block))) {
652       /* set new predecessors in array
653          n->in[0] remains the same block */
654       new_irn_arity = 1;
655       for(i = 1; i < old_irn_arity; i++)
656         if (!is_Bad((ir_node *)old_in[i])) {
657           n->in[new_irn_arity] = n->in[i];
658           is_backedge(n, i) ? set_backedge(n, new_irn_arity) : set_not_backedge(n, new_irn_arity);
659           ++new_irn_arity;
660         }
661
662       ARR_SETLEN(ir_node *, n->in, new_irn_arity);
663       ARR_SETLEN(int, n->attr.phi_backedge, new_irn_arity);
664     }
665
666   } /* n is a Phi node */
667 }
668
669 /*
670  * Removes Bad Bad predecessors from Blocks and the corresponding
671  * inputs to Phi nodes as in dead_node_elimination but without
672  * copying the graph.
673  * On walking up set the link field to NULL, on walking down call
674  * relink_bad_predecessors() (This function stores the old in array
675  * to the link field and sets a new in array if arity of predecessors
676  * changes).
677  */
678 void remove_bad_predecessors(ir_graph *irg) {
679   irg_walk_graph(irg, init_link, relink_bad_predecessors, NULL);
680 }
681
682
683 /*--------------------------------------------------------------------*/
684 /*  Functionality for inlining                                         */
685 /*--------------------------------------------------------------------*/
686
687 /**
688  * Copy node for inlineing.  Updates attributes that change when
689  * inlineing but not for dead node elimination.
690  *
691  * Copies the node by calling copy_node() and then updates the entity if
692  * it's a local one.  env must be a pointer of the frame type of the
693  * inlined procedure. The new entities must be in the link field of
694  * the entities.
695  */
696 static INLINE void
697 copy_node_inline (ir_node *n, void *env) {
698   ir_node *new;
699   type *frame_tp = (type *)env;
700
701   copy_node(n, NULL);
702   if (get_irn_op(n) == op_Sel) {
703     new = get_new_node (n);
704     assert(get_irn_op(new) == op_Sel);
705     if (get_entity_owner(get_Sel_entity(n)) == frame_tp) {
706       set_Sel_entity(new, get_entity_link(get_Sel_entity(n)));
707     }
708   } else if (get_irn_op(n) == op_Block) {
709     new = get_new_node (n);
710     new->attr.block.irg = current_ir_graph;
711   }
712 }
713
714 static void find_addr(ir_node *node, void *env)
715 {
716   if (get_irn_opcode(node) == iro_Proj) {
717     if (get_Proj_proj(node) == pn_Start_P_value_arg_base)
718       *(int *)env = 0;
719   }
720 }
721
722 /*
723  * currently, we cannot inline two cases:
724  * - call with compound arguments
725  * - graphs that take the address of a parameter
726  *
727  * check these conditions here
728  */
729 static int can_inline(ir_node *call, ir_graph *called_graph)
730 {
731   type *call_type = get_Call_type(call);
732   int params, ress, i, res;
733   assert(is_Method_type(call_type));
734
735   params = get_method_n_params(call_type);
736   ress   = get_method_n_ress(call_type);
737
738   /* check params */
739   for (i = 0; i < params; ++i) {
740     type *p_type = get_method_param_type(call_type, i);
741
742     if (is_compound_type(p_type))
743       return 0;
744   }
745
746   /* check res */
747   for (i = 0; i < ress; ++i) {
748     type *r_type = get_method_res_type(call_type, i);
749
750     if (is_compound_type(r_type))
751       return 0;
752   }
753
754   res = 1;
755   irg_walk_graph(called_graph, find_addr, NULL, &res);
756
757   return res;
758 }
759
760 int inline_method(ir_node *call, ir_graph *called_graph) {
761   ir_node *pre_call;
762   ir_node *post_call, *post_bl;
763   ir_node *in[5];
764   ir_node *end, *end_bl;
765   ir_node **res_pred;
766   ir_node **cf_pred;
767   ir_node *ret, *phi;
768   int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity;
769   int exc_handling;
770   type *called_frame;
771   irg_inline_property prop = get_irg_inline_property(called_graph);
772
773   if ( (prop != irg_inline_forced) &&
774        (!get_opt_optimize() || !get_opt_inline() || (prop == irg_inline_forbidden))) return 0;
775
776   /* Do not inline variadic functions. */
777   if (get_method_variadicity(get_entity_type(get_irg_entity(called_graph))) == variadicity_variadic)
778     return 0;
779
780   assert(get_method_n_params(get_entity_type(get_irg_entity(called_graph))) ==
781          get_method_n_params(get_Call_type(call)));
782
783   /*
784    * currently, we cannot inline two cases:
785    * - call with compound arguments
786    * - graphs that take the address of a parameter
787    */
788   if (! can_inline(call, called_graph))
789     return 0;
790
791   /* --  Turn off optimizations, this can cause problems when allocating new nodes. -- */
792   rem_opt = get_opt_optimize();
793   set_optimize(0);
794
795   /* Handle graph state */
796   assert(get_irg_phase_state(current_ir_graph) != phase_building);
797   assert(get_irg_pinned(current_ir_graph) == op_pin_state_pinned);
798   assert(get_irg_pinned(called_graph) == op_pin_state_pinned);
799   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
800     set_irg_outs_inconsistent(current_ir_graph);
801   set_irg_loopinfo_inconsistent(current_ir_graph);
802   set_irg_callee_info_state(current_ir_graph, irg_callee_info_inconsistent);
803
804   /* -- Check preconditions -- */
805   assert(get_irn_op(call) == op_Call);
806   /* @@@ does not work for InterfaceIII.java after cgana
807      assert(get_Call_type(call) == get_entity_type(get_irg_entity(called_graph)));
808      assert(smaller_type(get_entity_type(get_irg_entity(called_graph)),
809      get_Call_type(call)));
810   */
811   assert(get_type_tpop(get_Call_type(call)) == type_method);
812   if (called_graph == current_ir_graph) {
813     set_optimize(rem_opt);
814     return 0;
815   }
816
817   /* here we know we WILL inline, so inform the statistics */
818   hook_inline(call, called_graph);
819
820   /* -- Decide how to handle exception control flow: Is there a handler
821      for the Call node, or do we branch directly to End on an exception?
822      exc_handling:
823      0 There is a handler.
824      1 Branches to End.
825      2 Exception handling not represented in Firm. -- */
826   {
827     ir_node *proj, *Mproj = NULL, *Xproj = NULL;
828     for (proj = (ir_node *)get_irn_link(call); proj; proj = (ir_node *)get_irn_link(proj)) {
829       assert(get_irn_op(proj) == op_Proj);
830       if (get_Proj_proj(proj) == pn_Call_X_except) Xproj = proj;
831       if (get_Proj_proj(proj) == pn_Call_M_except) Mproj = proj;
832     }
833     if      (Mproj) { assert(Xproj); exc_handling = 0; } /*  Mproj           */
834     else if (Xproj) {                exc_handling = 1; } /* !Mproj &&  Xproj   */
835     else            {                exc_handling = 2; } /* !Mproj && !Xproj   */
836   }
837
838
839   /* --
840      the procedure and later replaces the Start node of the called graph.
841      Post_call is the old Call node and collects the results of the called
842      graph. Both will end up being a tuple.  -- */
843   post_bl = get_nodes_block(call);
844   set_irg_current_block(current_ir_graph, post_bl);
845   /* XxMxPxP of Start + parameter of Call */
846   in[pn_Start_X_initial_exec] = new_Jmp();
847   in[pn_Start_M]              = get_Call_mem(call);
848   in[pn_Start_P_frame_base]   = get_irg_frame(current_ir_graph);
849   in[pn_Start_P_globals]      = get_irg_globals(current_ir_graph);
850   in[pn_Start_T_args]         = new_Tuple(get_Call_n_params(call), get_Call_param_arr(call));
851   /* in[pn_Start_P_value_arg_base] = ??? */
852   pre_call = new_Tuple(5, in);
853   post_call = call;
854
855   /* --
856      The new block gets the ins of the old block, pre_call and all its
857      predecessors and all Phi nodes. -- */
858   part_block(pre_call);
859
860   /* -- Prepare state for dead node elimination -- */
861   /* Visited flags in calling irg must be >= flag in called irg.
862      Else walker and arity computation will not work. */
863   if (get_irg_visited(current_ir_graph) <= get_irg_visited(called_graph))
864     set_irg_visited(current_ir_graph, get_irg_visited(called_graph)+1);
865   if (get_irg_block_visited(current_ir_graph)< get_irg_block_visited(called_graph))
866     set_irg_block_visited(current_ir_graph, get_irg_block_visited(called_graph));
867   /* Set pre_call as new Start node in link field of the start node of
868      calling graph and pre_calls block as new block for the start block
869      of calling graph.
870      Further mark these nodes so that they are not visited by the
871      copying. */
872   set_irn_link(get_irg_start(called_graph), pre_call);
873   set_irn_visited(get_irg_start(called_graph), get_irg_visited(current_ir_graph));
874   set_irn_link(get_irg_start_block(called_graph), get_nodes_block(pre_call));
875   set_irn_visited(get_irg_start_block(called_graph), get_irg_visited(current_ir_graph));
876   set_irn_link(get_irg_bad(called_graph), get_irg_bad(current_ir_graph));
877   set_irn_visited(get_irg_bad(called_graph), get_irg_visited(current_ir_graph));
878
879   /* Initialize for compaction of in arrays */
880   inc_irg_block_visited(current_ir_graph);
881
882   /* -- Replicate local entities of the called_graph -- */
883   /* copy the entities. */
884   called_frame = get_irg_frame_type(called_graph);
885   for (i = 0; i < get_class_n_members(called_frame); i++) {
886     entity *new_ent, *old_ent;
887     old_ent = get_class_member(called_frame, i);
888     new_ent = copy_entity_own(old_ent, get_cur_frame_type());
889     set_entity_link(old_ent, new_ent);
890   }
891
892   /* visited is > than that of called graph.  With this trick visited will
893      remain unchanged so that an outer walker, e.g., searching the call nodes
894      to inline, calling this inline will not visit the inlined nodes. */
895   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
896
897   /* -- Performing dead node elimination inlines the graph -- */
898   /* Copies the nodes to the obstack of current_ir_graph. Updates links to new
899      entities. */
900   /* @@@ endless loops are not copied!! -- they should be, I think... */
901   irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds,
902            get_irg_frame_type(called_graph));
903
904   /* Repair called_graph */
905   set_irg_visited(called_graph, get_irg_visited(current_ir_graph));
906   set_irg_block_visited(called_graph, get_irg_block_visited(current_ir_graph));
907   set_Block_block_visited(get_irg_start_block(called_graph), 0);
908
909   /* -- Merge the end of the inlined procedure with the call site -- */
910   /* We will turn the old Call node into a Tuple with the following
911      predecessors:
912      -1:  Block of Tuple.
913      0: Phi of all Memories of Return statements.
914      1: Jmp from new Block that merges the control flow from all exception
915      predecessors of the old end block.
916      2: Tuple of all arguments.
917      3: Phi of Exception memories.
918      In case the old Call directly branches to End on an exception we don't
919      need the block merging all exceptions nor the Phi of the exception
920      memories.
921   */
922
923   /* -- Precompute some values -- */
924   end_bl = get_new_node(get_irg_end_block(called_graph));
925   end = get_new_node(get_irg_end(called_graph));
926   arity = get_irn_arity(end_bl);    /* arity = n_exc + n_ret  */
927   n_res = get_method_n_ress(get_Call_type(call));
928
929   res_pred = xmalloc (n_res * sizeof(*res_pred));
930   cf_pred  = xmalloc (arity * sizeof(*res_pred));
931
932   set_irg_current_block(current_ir_graph, post_bl); /* just to make sure */
933
934   /* -- archive keepalives -- */
935   irn_arity = get_irn_arity(end);
936   for (i = 0; i < irn_arity; i++)
937     add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
938
939   /* The new end node will die.  We need not free as the in array is on the obstack:
940      copy_node() only generated 'D' arrays. */
941
942   /* -- Replace Return nodes by Jump nodes. -- */
943   n_ret = 0;
944   for (i = 0; i < arity; i++) {
945     ir_node *ret;
946     ret = get_irn_n(end_bl, i);
947     if (get_irn_op(ret) == op_Return) {
948       cf_pred[n_ret] = new_r_Jmp(current_ir_graph, get_nodes_block(ret));
949       n_ret++;
950     }
951   }
952   set_irn_in(post_bl, n_ret, cf_pred);
953
954   /* -- Build a Tuple for all results of the method.
955      Add Phi node if there was more than one Return.  -- */
956   turn_into_tuple(post_call, 4);
957   /* First the Memory-Phi */
958   n_ret = 0;
959   for (i = 0; i < arity; i++) {
960     ret = get_irn_n(end_bl, i);
961     if (get_irn_op(ret) == op_Return) {
962       cf_pred[n_ret] = get_Return_mem(ret);
963       n_ret++;
964     }
965   }
966   phi = new_Phi(n_ret, cf_pred, mode_M);
967   set_Tuple_pred(call, pn_Call_M_regular, 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   /* Now the real results */
974   if (n_res > 0) {
975     for (j = 0; j < n_res; j++) {
976       n_ret = 0;
977       for (i = 0; i < arity; i++) {
978         ret = get_irn_n(end_bl, i);
979         if (get_irn_op(ret) == op_Return) {
980           cf_pred[n_ret] = get_Return_res(ret, j);
981           n_ret++;
982         }
983       }
984       if (n_ret > 0)
985         phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0]));
986       else
987         phi = new_Bad();
988       res_pred[j] = phi;
989       /* Conserve Phi-list for further inlinings -- but might be optimized */
990       if (get_nodes_block(phi) == post_bl) {
991         set_irn_link(phi, get_irn_link(post_bl));
992         set_irn_link(post_bl, phi);
993       }
994     }
995     set_Tuple_pred(call, pn_Call_T_result, new_Tuple(n_res, res_pred));
996   } else {
997     set_Tuple_pred(call, pn_Call_T_result, new_Bad());
998   }
999   /* Finally the exception control flow.
1000      We have two (three) possible situations:
1001      First if the Call branches to an exception handler: We need to add a Phi node to
1002      collect the memory containing the exception objects.  Further we need
1003      to add another block to get a correct representation of this Phi.  To
1004      this block we add a Jmp that resolves into the X output of the Call
1005      when the Call is turned into a tuple.
1006      Second the Call branches to End, the exception is not handled.  Just
1007      add all inlined exception branches to the End node.
1008      Third: there is no Exception edge at all. Handle as case two. */
1009   if (exc_handling == 0) {
1010     n_exc = 0;
1011     for (i = 0; i < arity; i++) {
1012       ir_node *ret;
1013       ret = get_irn_n(end_bl, i);
1014       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
1015         cf_pred[n_exc] = ret;
1016         n_exc++;
1017       }
1018     }
1019     if (n_exc > 0) {
1020       new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
1021       set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
1022       /* The Phi for the memories with the exception objects */
1023       n_exc = 0;
1024       for (i = 0; i < arity; i++) {
1025         ir_node *ret;
1026         ret = skip_Proj(get_irn_n(end_bl, i));
1027         if (get_irn_op(ret) == op_Call) {
1028           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 3);
1029           n_exc++;
1030         } else if (is_fragile_op(ret)) {
1031           /* We rely that all cfops have the memory output at the same position. */
1032           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 0);
1033           n_exc++;
1034         } else if (get_irn_op(ret) == op_Raise) {
1035           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 1);
1036           n_exc++;
1037         }
1038       }
1039       set_Tuple_pred(call, pn_Call_M_except, new_Phi(n_exc, cf_pred, mode_M));
1040     } else {
1041       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1042       set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1043     }
1044   } else {
1045     ir_node *main_end_bl;
1046     int main_end_bl_arity;
1047     ir_node **end_preds;
1048
1049     /* assert(exc_handling == 1 || no exceptions. ) */
1050     n_exc = 0;
1051     for (i = 0; i < arity; i++) {
1052       ir_node *ret = get_irn_n(end_bl, i);
1053
1054       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
1055         cf_pred[n_exc] = ret;
1056         n_exc++;
1057       }
1058     }
1059     main_end_bl = get_irg_end_block(current_ir_graph);
1060     main_end_bl_arity = get_irn_arity(main_end_bl);
1061     end_preds =  xmalloc ((n_exc + main_end_bl_arity) * sizeof(*end_preds));
1062
1063     for (i = 0; i < main_end_bl_arity; ++i)
1064       end_preds[i] = get_irn_n(main_end_bl, i);
1065     for (i = 0; i < n_exc; ++i)
1066       end_preds[main_end_bl_arity + i] = cf_pred[i];
1067     set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
1068     set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1069     set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1070     free(end_preds);
1071   }
1072   free(res_pred);
1073   free(cf_pred);
1074
1075 #if 0  /* old. now better, correcter, faster implementation. */
1076   if (n_exc > 0) {
1077     /* -- If the exception control flow from the inlined Call directly
1078        branched to the end block we now have the following control
1079        flow predecessor pattern: ProjX -> Tuple -> Jmp.  We must
1080        remove the Jmp along with it's empty block and add Jmp's
1081        predecessors as predecessors of this end block.  No problem if
1082        there is no exception, because then branches Bad to End which
1083        is fine. --
1084        @@@ can't we know this beforehand: by getting the Proj(1) from
1085        the Call link list and checking whether it goes to Proj. */
1086     /* find the problematic predecessor of the end block. */
1087     end_bl = get_irg_end_block(current_ir_graph);
1088     for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
1089       cf_op = get_Block_cfgpred(end_bl, i);
1090       if (get_irn_op(cf_op) == op_Proj) {
1091         cf_op = get_Proj_pred(cf_op);
1092         if ((get_irn_op(cf_op) == op_Tuple) && (cf_op == call)) {
1093           /*  There are unoptimized tuples from inlineing before when no exc */
1094           assert(get_Proj_proj(get_Block_cfgpred(end_bl, i)) == pn_Call_X_except);
1095           cf_op = get_Tuple_pred(cf_op, pn_Call_X_except);
1096           assert(get_irn_op(cf_op) == op_Jmp);
1097           break;
1098         }
1099       }
1100     }
1101     /* repair */
1102     if (i < get_Block_n_cfgpreds(end_bl)) {
1103       bl = get_nodes_block(cf_op);
1104       arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
1105       cf_pred = xmalloc (arity * sizeof(*cf_pred));
1106       for (j = 0; j < i; j++)
1107         cf_pred[j] = get_Block_cfgpred(end_bl, j);
1108       for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
1109         cf_pred[j] = get_Block_cfgpred(bl, j-i);
1110       for (j = j; j < arity; j++)
1111         cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
1112       set_irn_in(end_bl, arity, cf_pred);
1113       free(cf_pred);
1114       /*  Remove the exception pred from post-call Tuple. */
1115       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1116     }
1117   }
1118 #endif
1119
1120   /* --  Turn CSE back on. -- */
1121   set_optimize(rem_opt);
1122
1123   return 1;
1124 }
1125
1126 /********************************************************************/
1127 /* Apply inlineing to small methods.                                */
1128 /********************************************************************/
1129
1130 /* It makes no sense to inline too many calls in one procedure. Anyways,
1131    I didn't get a version with NEW_ARR_F to run. */
1132 #define MAX_INLINE 1024
1133
1134 /**
1135  * environment for inlining small irgs
1136  */
1137 typedef struct _inline_env_t {
1138   int pos;
1139   ir_node *calls[MAX_INLINE];
1140 } inline_env_t;
1141
1142 /**
1143  * Returns the irg called from a Call node. If the irg is not
1144  * known, NULL is returned.
1145  */
1146 static ir_graph *get_call_called_irg(ir_node *call) {
1147   ir_node *addr;
1148   ir_graph *called_irg = NULL;
1149
1150   assert(get_irn_op(call) == op_Call);
1151
1152   addr = get_Call_ptr(call);
1153   if ((get_irn_op(addr) == op_SymConst) && (get_SymConst_kind (addr) == symconst_addr_ent)) {
1154     called_irg = get_entity_irg(get_SymConst_entity(addr));
1155   }
1156
1157   return called_irg;
1158 }
1159
1160 static void collect_calls(ir_node *call, void *env) {
1161   ir_node *addr;
1162
1163   if (get_irn_op(call) != op_Call) return;
1164
1165   addr = get_Call_ptr(call);
1166
1167   if (get_irn_op(addr) == op_SymConst) {
1168     if (get_SymConst_kind(addr) == symconst_addr_ent) {
1169       ir_graph *called_irg = get_entity_irg(get_SymConst_entity(addr));
1170       inline_env_t *ienv = (inline_env_t *)env;
1171       if (called_irg && ienv->pos < MAX_INLINE) {
1172         /* The Call node calls a locally defined method.  Remember to inline. */
1173         ienv->calls[ienv->pos++] = call;
1174       }
1175     }
1176   }
1177 }
1178
1179 /**
1180  * Inlines all small methods at call sites where the called address comes
1181  * from a Const node that references the entity representing the called
1182  * method.
1183  * The size argument is a rough measure for the code size of the method:
1184  * Methods where the obstack containing the firm graph is smaller than
1185  * size are inlined.
1186  */
1187 void inline_small_irgs(ir_graph *irg, int size) {
1188   int i;
1189   ir_graph *rem = current_ir_graph;
1190   inline_env_t env /* = {0, NULL}*/;
1191
1192   if (!(get_opt_optimize() && get_opt_inline())) return;
1193
1194   current_ir_graph = irg;
1195   /* Handle graph state */
1196   assert(get_irg_phase_state(current_ir_graph) != phase_building);
1197   free_callee_info(current_ir_graph);
1198
1199   /* Find Call nodes to inline.
1200      (We can not inline during a walk of the graph, as inlineing the same
1201      method several times changes the visited flag of the walked graph:
1202      after the first inlineing visited of the callee equals visited of
1203      the caller.  With the next inlineing both are increased.) */
1204   env.pos = 0;
1205   irg_walk(get_irg_end(irg), NULL, collect_calls, &env);
1206
1207   if ((env.pos > 0) && (env.pos < MAX_INLINE)) {
1208     /* There are calls to inline */
1209     collect_phiprojs(irg);
1210     for (i = 0; i < env.pos; i++) {
1211       ir_graph *callee;
1212       callee = get_entity_irg(get_SymConst_entity(get_Call_ptr(env.calls[i])));
1213       if (((_obstack_memory_used(callee->obst) - (int)obstack_room(callee->obst)) < size) ||
1214         (get_irg_inline_property(callee) == irg_inline_forced)) {
1215         inline_method(env.calls[i], callee);
1216       }
1217     }
1218   }
1219
1220   current_ir_graph = rem;
1221 }
1222
1223 /**
1224  * Environment for inlining irgs.
1225  */
1226 typedef struct {
1227   int n_nodes;       /**< Nodes in graph except Id, Tuple, Proj, Start, End */
1228   int n_nodes_orig;  /**< for statistics */
1229   eset *call_nodes;  /**< All call nodes in this graph */
1230   int n_call_nodes;
1231   int n_call_nodes_orig; /**< for statistics */
1232   int n_callers;   /**< Number of known graphs that call this graphs. */
1233   int n_callers_orig; /**< for statistics */
1234 } inline_irg_env;
1235
1236 /**
1237  * Allocate a new environment for inlining.
1238  */
1239 static inline_irg_env *new_inline_irg_env(void) {
1240   inline_irg_env *env    = xmalloc(sizeof(*env));
1241   env->n_nodes           = -2; /* do not count count Start, End */
1242   env->n_nodes_orig      = -2; /* do not count Start, End */
1243   env->call_nodes        = eset_create();
1244   env->n_call_nodes      = 0;
1245   env->n_call_nodes_orig = 0;
1246   env->n_callers         = 0;
1247   env->n_callers_orig    = 0;
1248   return env;
1249 }
1250
1251 /**
1252  * destroy an environment for inlining.
1253  */
1254 static void free_inline_irg_env(inline_irg_env *env) {
1255   eset_destroy(env->call_nodes);
1256   free(env);
1257 }
1258
1259 /**
1260  * post-walker: collect all calls in the inline-environment
1261  * of a graph and sum some statistics.
1262  */
1263 static void collect_calls2(ir_node *call, void *env) {
1264   inline_irg_env *x = (inline_irg_env *)env;
1265   ir_op *op = get_irn_op(call);
1266   ir_graph *callee;
1267
1268   /* count meaningful nodes in irg */
1269   if (op != op_Proj && op != op_Tuple && op != op_Sync) {
1270     x->n_nodes++;
1271     x->n_nodes_orig++;
1272   }
1273
1274   if (op != op_Call) return;
1275
1276   /* collect all call nodes */
1277   eset_insert(x->call_nodes, call);
1278   x->n_call_nodes++;
1279   x->n_call_nodes_orig++;
1280
1281   /* count all static callers */
1282   callee = get_call_called_irg(call);
1283   if (callee) {
1284     inline_irg_env *callee_env = get_irg_link(callee);
1285     callee_env->n_callers++;
1286     callee_env->n_callers_orig++;
1287   }
1288 }
1289
1290 /**
1291  * Returns TRUE if the number of callers in 0 in the irg's environment,
1292  * hence this irg is a leave.
1293  */
1294 INLINE static int is_leave(ir_graph *irg) {
1295   return (((inline_irg_env *)get_irg_link(irg))->n_call_nodes == 0);
1296 }
1297
1298 /**
1299  * Returns TRUE if the number of callers is smaller size in the irg's environment.
1300  */
1301 INLINE static int is_smaller(ir_graph *callee, int size) {
1302   return (((inline_irg_env *)get_irg_link(callee))->n_nodes < size);
1303 }
1304
1305
1306 /*
1307  * Inlines small leave methods at call sites where the called address comes
1308  * from a Const node that references the entity representing the called
1309  * method.
1310  * The size argument is a rough measure for the code size of the method:
1311  * Methods where the obstack containing the firm graph is smaller than
1312  * size are inlined.
1313  */
1314 void inline_leave_functions(int maxsize, int leavesize, int size) {
1315   inline_irg_env *env;
1316   int i, n_irgs = get_irp_n_irgs();
1317   ir_graph *rem = current_ir_graph;
1318   int did_inline = 1;
1319
1320   if (!(get_opt_optimize() && get_opt_inline())) return;
1321
1322   /* extend all irgs by a temporary data structure for inlining. */
1323   for (i = 0; i < n_irgs; ++i)
1324     set_irg_link(get_irp_irg(i), new_inline_irg_env());
1325
1326   /* Precompute information in temporary data structure. */
1327   for (i = 0; i < n_irgs; ++i) {
1328     current_ir_graph = get_irp_irg(i);
1329     assert(get_irg_phase_state(current_ir_graph) != phase_building);
1330     free_callee_info(current_ir_graph);
1331
1332     irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2,
1333              get_irg_link(current_ir_graph));
1334   }
1335
1336   /* -- and now inline. -- */
1337
1338   /* Inline leaves recursively -- we might construct new leaves. */
1339   while (did_inline) {
1340     did_inline = 0;
1341
1342     for (i = 0; i < n_irgs; ++i) {
1343       ir_node *call;
1344       int phiproj_computed = 0;
1345
1346       current_ir_graph = get_irp_irg(i);
1347       env = (inline_irg_env *)get_irg_link(current_ir_graph);
1348
1349       for (call = eset_first(env->call_nodes); call; call = eset_next(env->call_nodes)) {
1350         ir_graph *callee;
1351
1352         if (get_irn_op(call) == op_Tuple) continue;   /* We already have inlined this call. */
1353         callee = get_call_called_irg(call);
1354
1355         if (env->n_nodes > maxsize) continue; // break;
1356
1357         if (callee && (is_leave(callee) && is_smaller(callee, leavesize))) {
1358           if (!phiproj_computed) {
1359             phiproj_computed = 1;
1360             collect_phiprojs(current_ir_graph);
1361           }
1362           did_inline = inline_method(call, callee);
1363
1364           if (did_inline) {
1365             /* Do some statistics */
1366             inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1367             env->n_call_nodes --;
1368             env->n_nodes += callee_env->n_nodes;
1369             callee_env->n_callers--;
1370           }
1371         }
1372       }
1373     }
1374   }
1375
1376   /* inline other small functions. */
1377   for (i = 0; i < n_irgs; ++i) {
1378     ir_node *call;
1379     eset *walkset;
1380     int phiproj_computed = 0;
1381
1382     current_ir_graph = get_irp_irg(i);
1383     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1384
1385     /* we can not walk and change a set, nor remove from it.
1386        So recompute.*/
1387     walkset = env->call_nodes;
1388     env->call_nodes = eset_create();
1389     for (call = eset_first(walkset); call; call = eset_next(walkset)) {
1390       ir_graph *callee;
1391
1392       if (get_irn_op(call) == op_Tuple) continue;   /* We already inlined. */
1393       callee = get_call_called_irg(call);
1394
1395       if (callee &&
1396           ((is_smaller(callee, size) && (env->n_nodes < maxsize)) ||    /* small function */
1397            (get_irg_inline_property(callee) == irg_inline_forced))) {
1398         if (!phiproj_computed) {
1399             phiproj_computed = 1;
1400             collect_phiprojs(current_ir_graph);
1401         }
1402         if (inline_method(call, callee)) {
1403           inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1404           env->n_call_nodes--;
1405           eset_insert_all(env->call_nodes, callee_env->call_nodes);  /* @@@ ??? This are the wrong nodes !? Not the copied ones. */
1406           env->n_call_nodes += callee_env->n_call_nodes;
1407           env->n_nodes += callee_env->n_nodes;
1408           callee_env->n_callers--;
1409         }
1410       } else {
1411         eset_insert(env->call_nodes, call);
1412       }
1413     }
1414     eset_destroy(walkset);
1415   }
1416
1417   for (i = 0; i < n_irgs; ++i) {
1418     current_ir_graph = get_irp_irg(i);
1419 #if 0
1420     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1421     if ((env->n_call_nodes_orig != env->n_call_nodes) ||
1422         (env->n_callers_orig != env->n_callers))
1423       printf("Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
1424              env->n_nodes_orig, env->n_nodes, env->n_call_nodes_orig, env->n_call_nodes,
1425              env->n_callers_orig, env->n_callers,
1426              get_entity_name(get_irg_entity(current_ir_graph)));
1427 #endif
1428     free_inline_irg_env((inline_irg_env *)get_irg_link(current_ir_graph));
1429   }
1430
1431   current_ir_graph = rem;
1432 }
1433
1434 /*******************************************************************/
1435 /*  Code Placement.  Pins all floating nodes to a block where they */
1436 /*  will be executed only if needed.                               */
1437 /*******************************************************************/
1438
1439 /**
1440  * Returns non-zero, is a block is not reachable from Start.
1441  *
1442  * @param block  the block to test
1443  */
1444 static int
1445 is_Block_unreachable(ir_node *block) {
1446   return is_Block_dead(block) || get_Block_dom_depth(block) < 0;
1447 }
1448
1449 /**
1450  * Find the earliest correct block for N.  --- Place N into the
1451  * same Block as its dominance-deepest Input.
1452  *
1453  * We have to avoid calls to get_nodes_block() here
1454  * because the graph is floating.
1455  *
1456  * move_out_of_loops() expects that place_floats_early() have placed
1457  * all "living" nodes into a living block. That's why we must
1458  * move nodes in dead block with "live" successors into a valid
1459  * block.
1460  * We move them just into the same block as it's successor (or
1461  * in case of a Phi into the effective use block). For Phi successors,
1462  * this may still be a dead block, but then there is no real use, as
1463  * the control flow will be dead later.
1464  */
1465 static void
1466 place_floats_early(ir_node *n, pdeq *worklist)
1467 {
1468   int i, irn_arity;
1469
1470   /* we must not run into an infinite loop */
1471   assert(irn_not_visited(n));
1472   mark_irn_visited(n);
1473
1474   /* Place floating nodes. */
1475   if (get_irn_pinned(n) == op_pin_state_floats) {
1476     ir_node *curr_block = get_irn_n(n, -1);
1477     int in_dead_block   = is_Block_unreachable(curr_block);
1478     int depth           = 0;
1479     ir_node *b          = NULL;   /* The block to place this node in */
1480
1481     assert(get_irn_op(n) != op_Block);
1482
1483     if ((get_irn_op(n) == op_Const) ||
1484         (get_irn_op(n) == op_SymConst) ||
1485         (is_Bad(n)) ||
1486         (get_irn_op(n) == op_Unknown)) {
1487       /* These nodes will not be placed by the loop below. */
1488       b = get_irg_start_block(current_ir_graph);
1489       depth = 1;
1490     }
1491
1492     /* find the block for this node. */
1493     irn_arity = get_irn_arity(n);
1494     for (i = 0; i < irn_arity; i++) {
1495       ir_node *pred = get_irn_n(n, i);
1496       ir_node *pred_block;
1497
1498       if ((irn_not_visited(pred))
1499          && (get_irn_pinned(pred) == op_pin_state_floats)) {
1500
1501         /*
1502          * If the current node is NOT in a dead block, but one of its
1503          * predecessors is, we must move the predecessor to a live block.
1504          * Such thing can happen, if global CSE chose a node from a dead block.
1505          * We move it simple to our block.
1506          * Note that neither Phi nor End nodes are floating, so we don't
1507          * need to handle them here.
1508          */
1509         if (! in_dead_block) {
1510           if (get_irn_pinned(pred) == op_pin_state_floats &&
1511               is_Block_unreachable(get_irn_n(pred, -1)))
1512             set_nodes_block(pred, curr_block);
1513         }
1514         place_floats_early(pred, worklist);
1515       }
1516
1517       /*
1518        * A node in the Bad block must stay in the bad block,
1519        * so don't compute a new block for it.
1520        */
1521       if (in_dead_block)
1522         continue;
1523
1524       /* Because all loops contain at least one op_pin_state_pinned node, now all
1525          our inputs are either op_pin_state_pinned or place_early() has already
1526          been finished on them.  We do not have any unfinished inputs!  */
1527       pred_block = get_irn_n(pred, -1);
1528       if ((!is_Block_dead(pred_block)) &&
1529           (get_Block_dom_depth(pred_block) > depth)) {
1530         b = pred_block;
1531         depth = get_Block_dom_depth(pred_block);
1532       }
1533       /* Avoid that the node is placed in the Start block */
1534       if ((depth == 1) && (get_Block_dom_depth(get_irn_n(n, -1)) > 1)) {
1535         b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
1536         assert(b != get_irg_start_block(current_ir_graph));
1537         depth = 2;
1538       }
1539     }
1540     if (b)
1541       set_nodes_block(n, b);
1542   }
1543
1544   /*
1545    * Add predecessors of non floating nodes and non-floating predecessors
1546    * of floating nodes to worklist and fix their blocks if the are in dead block.
1547    */
1548   irn_arity = get_irn_arity(n);
1549
1550   if (get_irn_op(n) == op_End) {
1551     /*
1552      * Simplest case: End node. Predecessors are keep-alives,
1553      * no need to move out of dead block.
1554      */
1555     for (i = -1; i < irn_arity; ++i) {
1556       ir_node *pred = get_irn_n(n, i);
1557       if (irn_not_visited(pred))
1558         pdeq_putr(worklist, pred);
1559     }
1560   }
1561   else if (is_Block(n)) {
1562     /*
1563      * Blocks: Predecessors are control flow, no need to move
1564      * them out of dead block.
1565      */
1566     for (i = irn_arity - 1; i >= 0; --i) {
1567       ir_node *pred = get_irn_n(n, i);
1568       if (irn_not_visited(pred))
1569         pdeq_putr(worklist, pred);
1570     }
1571   }
1572   else if (is_Phi(n)) {
1573     ir_node *pred;
1574     ir_node *curr_block = get_irn_n(n, -1);
1575     int in_dead_block   = is_Block_unreachable(curr_block);
1576
1577     /*
1578      * Phi nodes: move nodes from dead blocks into the effective use
1579      * of the Phi-input if the Phi is not in a bad block.
1580      */
1581     pred = get_irn_n(n, -1);
1582     if (irn_not_visited(pred))
1583       pdeq_putr(worklist, pred);
1584
1585     for (i = irn_arity - 1; i >= 0; --i) {
1586       ir_node *pred = get_irn_n(n, i);
1587
1588       if (irn_not_visited(pred)) {
1589         if (! in_dead_block &&
1590             get_irn_pinned(pred) == op_pin_state_floats &&
1591             is_Block_unreachable(get_irn_n(pred, -1))) {
1592           set_nodes_block(pred, get_Block_cfgpred_block(curr_block, i));
1593         }
1594         pdeq_putr(worklist, pred);
1595       }
1596     }
1597   }
1598   else {
1599     ir_node *pred;
1600     ir_node *curr_block = get_irn_n(n, -1);
1601     int in_dead_block   = is_Block_unreachable(curr_block);
1602
1603     /*
1604      * All other nodes: move nodes from dead blocks into the same block.
1605      */
1606     pred = get_irn_n(n, -1);
1607     if (irn_not_visited(pred))
1608       pdeq_putr(worklist, pred);
1609
1610     for (i = irn_arity - 1; i >= 0; --i) {
1611       ir_node *pred = get_irn_n(n, i);
1612
1613       if (irn_not_visited(pred)) {
1614         if (! in_dead_block &&
1615             get_irn_pinned(pred) == op_pin_state_floats &&
1616             is_Block_unreachable(get_irn_n(pred, -1))) {
1617           set_nodes_block(pred, curr_block);
1618         }
1619         pdeq_putr(worklist, pred);
1620       }
1621     }
1622   }
1623 }
1624
1625 /**
1626  * Floating nodes form subgraphs that begin at nodes as Const, Load,
1627  * Start, Call and that end at op_pin_state_pinned nodes as Store, Call.  Place_early
1628  * places all floating nodes reachable from its argument through floating
1629  * nodes and adds all beginnings at op_pin_state_pinned nodes to the worklist.
1630  */
1631 static INLINE void place_early(pdeq *worklist) {
1632   assert(worklist);
1633   inc_irg_visited(current_ir_graph);
1634
1635   /* this inits the worklist */
1636   place_floats_early(get_irg_end(current_ir_graph), worklist);
1637
1638   /* Work the content of the worklist. */
1639   while (!pdeq_empty(worklist)) {
1640     ir_node *n = pdeq_getl(worklist);
1641     if (irn_not_visited(n))
1642       place_floats_early(n, worklist);
1643   }
1644
1645   set_irg_outs_inconsistent(current_ir_graph);
1646   set_irg_pinned(current_ir_graph, op_pin_state_pinned);
1647 }
1648
1649 /**
1650  * Compute the deepest common ancestor of block and dca.
1651  */
1652 static ir_node *calc_dca(ir_node *dca, ir_node *block)
1653 {
1654   assert(block);
1655
1656   /* we do not want to place nodes in dead blocks */
1657   if (is_Block_dead(block))
1658     return dca;
1659
1660   /* We found a first legal placement. */
1661   if (!dca) return block;
1662
1663   /* Find a placement that is dominates both, dca and block. */
1664   while (get_Block_dom_depth(block) > get_Block_dom_depth(dca))
1665     block = get_Block_idom(block);
1666
1667   while (get_Block_dom_depth(dca) > get_Block_dom_depth(block)) {
1668     dca = get_Block_idom(dca);
1669   }
1670
1671   while (block != dca)
1672     { block = get_Block_idom(block); dca = get_Block_idom(dca); }
1673
1674   return dca;
1675 }
1676
1677 /** Deepest common dominance ancestor of DCA and CONSUMER of PRODUCER.
1678  * I.e., DCA is the block where we might place PRODUCER.
1679  * A data flow edge points from producer to consumer.
1680  */
1681 static ir_node *
1682 consumer_dom_dca(ir_node *dca, ir_node *consumer, ir_node *producer)
1683 {
1684   ir_node *block = NULL;
1685
1686   /* Compute the latest block into which we can place a node so that it is
1687      before consumer. */
1688   if (get_irn_op(consumer) == op_Phi) {
1689     /* our consumer is a Phi-node, the effective use is in all those
1690        blocks through which the Phi-node reaches producer */
1691     int i, irn_arity;
1692     ir_node *phi_block = get_nodes_block(consumer);
1693     irn_arity = get_irn_arity(consumer);
1694
1695     for (i = 0;  i < irn_arity; i++) {
1696       if (get_irn_n(consumer, i) == producer) {
1697         ir_node *new_block = get_nodes_block(get_Block_cfgpred(phi_block, i));
1698
1699         if (! is_Block_unreachable(new_block))
1700           block = calc_dca(block, new_block);
1701       }
1702     }
1703
1704     if (! block)
1705       block = get_irn_n(producer, -1);
1706   }
1707   else {
1708     assert(is_no_Block(consumer));
1709     block = get_nodes_block(consumer);
1710   }
1711
1712   /* Compute the deepest common ancestor of block and dca. */
1713   return calc_dca(dca, block);
1714 }
1715
1716 /* FIXME: the name clashes here with the function from ana/field_temperature.c
1717  * please rename. */
1718 static INLINE int get_irn_loop_depth(ir_node *n) {
1719   return get_loop_depth(get_irn_loop(n));
1720 }
1721
1722 /**
1723  * Move n to a block with less loop depth than it's current block. The
1724  * new block must be dominated by early.
1725  *
1726  * @param n      the node that should be moved
1727  * @param early  the earliest block we can n move to
1728  */
1729 static void
1730 move_out_of_loops (ir_node *n, ir_node *early)
1731 {
1732   ir_node *best, *dca;
1733   assert(n && early);
1734
1735
1736   /* Find the region deepest in the dominator tree dominating
1737      dca with the least loop nesting depth, but still dominated
1738      by our early placement. */
1739   dca = get_nodes_block(n);
1740
1741   best = dca;
1742   while (dca != early) {
1743     dca = get_Block_idom(dca);
1744     if (!dca || is_Bad(dca)) break; /* may be Bad if not reachable from Start */
1745     if (get_irn_loop_depth(dca) < get_irn_loop_depth(best)) {
1746       best = dca;
1747     }
1748   }
1749   if (best != get_nodes_block(n)) {
1750     /* debug output
1751     printf("Moving out of loop: "); DDMN(n);
1752     printf(" Outermost block: "); DDMN(early);
1753     printf(" Best block: "); DDMN(best);
1754     printf(" Innermost block: "); DDMN(get_nodes_block(n));
1755     */
1756     set_nodes_block(n, best);
1757   }
1758 }
1759
1760 /**
1761  * Find the latest legal block for N and place N into the
1762  * `optimal' Block between the latest and earliest legal block.
1763  * The `optimal' block is the dominance-deepest block of those
1764  * with the least loop-nesting-depth.  This places N out of as many
1765  * loops as possible and then makes it as control dependent as
1766  * possible.
1767  */
1768 static void
1769 place_floats_late(ir_node *n, pdeq *worklist)
1770 {
1771   int i;
1772   ir_node *early_blk;
1773
1774   assert(irn_not_visited(n)); /* no multiple placement */
1775
1776   mark_irn_visited(n);
1777
1778   /* no need to place block nodes, control nodes are already placed. */
1779   if ((get_irn_op(n) != op_Block) &&
1780       (!is_cfop(n)) &&
1781       (get_irn_mode(n) != mode_X)) {
1782     /* Remember the early_blk placement of this block to move it
1783        out of loop no further than the early_blk placement. */
1784     early_blk = get_irn_n(n, -1);
1785
1786     /*
1787      * BEWARE: Here we also get code, that is live, but
1788      * was in a dead block.  If the node is life, but because
1789      * of CSE in a dead block, we still might need it.
1790      */
1791
1792     /* Assure that our users are all placed, except the Phi-nodes.
1793        --- Each data flow cycle contains at least one Phi-node.  We
1794        have to break the `user has to be placed before the
1795        producer' dependence cycle and the Phi-nodes are the
1796        place to do so, because we need to base our placement on the
1797        final region of our users, which is OK with Phi-nodes, as they
1798        are op_pin_state_pinned, and they never have to be placed after a
1799        producer of one of their inputs in the same block anyway. */
1800     for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
1801       ir_node *succ = get_irn_out(n, i);
1802       if (irn_not_visited(succ) && (get_irn_op(succ) != op_Phi))
1803         place_floats_late(succ, worklist);
1804     }
1805
1806     if (! is_Block_dead(early_blk)) {
1807       /* do only move things that where not dead */
1808
1809       /* We have to determine the final block of this node... except for
1810          constants. */
1811       if ((get_irn_pinned(n) == op_pin_state_floats) &&
1812           (get_irn_op(n) != op_Const) &&
1813           (get_irn_op(n) != op_SymConst)) {
1814         ir_node *dca = NULL;  /* deepest common ancestor in the
1815                      dominator tree of all nodes'
1816                      blocks depending on us; our final
1817                      placement has to dominate DCA. */
1818         for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
1819           ir_node *succ = get_irn_out(n, i);
1820           ir_node *succ_blk;
1821
1822           if (get_irn_op(succ) == op_End) {
1823             /*
1824              * This consumer is the End node, a keep alive edge.
1825              * This is not a real consumer, so we ignore it
1826              */
1827             continue;
1828           }
1829
1830           /* ignore if succ is in dead code */
1831           succ_blk = get_irn_n(succ, -1);
1832           if (is_Block_unreachable(succ_blk))
1833             continue;
1834           dca = consumer_dom_dca(dca, succ, n);
1835         }
1836         if (dca) {
1837           set_nodes_block(n, dca);
1838           move_out_of_loops(n, early_blk);
1839         }
1840       }
1841     }
1842   }
1843
1844   /* Add predecessors of all non-floating nodes on list. (Those of floating
1845      nodes are placed already and therefore are marked.)  */
1846   for (i = 0; i < get_irn_n_outs(n); i++) {
1847     ir_node *succ = get_irn_out(n, i);
1848     if (irn_not_visited(get_irn_out(n, i))) {
1849       pdeq_putr(worklist, succ);
1850     }
1851   }
1852 }
1853
1854 static INLINE void place_late(pdeq *worklist) {
1855   assert(worklist);
1856   inc_irg_visited(current_ir_graph);
1857
1858   /* This fills the worklist initially. */
1859   place_floats_late(get_irg_start_block(current_ir_graph), worklist);
1860
1861   /* And now empty the worklist again... */
1862   while (!pdeq_empty(worklist)) {
1863     ir_node *n = pdeq_getl(worklist);
1864     if (irn_not_visited(n))
1865       place_floats_late(n, worklist);
1866   }
1867 }
1868
1869 void place_code(ir_graph *irg) {
1870   pdeq *worklist;
1871   ir_graph *rem = current_ir_graph;
1872
1873   current_ir_graph = irg;
1874
1875   if (!(get_opt_optimize() && get_opt_global_cse())) return;
1876
1877   /* Handle graph state */
1878   assert(get_irg_phase_state(irg) != phase_building);
1879   if (get_irg_dom_state(irg) != dom_consistent)
1880     compute_doms(irg);
1881
1882   if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) {
1883     free_loop_information(irg);
1884     construct_backedges(irg);
1885   }
1886
1887   /* Place all floating nodes as early as possible. This guarantees
1888      a legal code placement. */
1889   worklist = new_pdeq();
1890   place_early(worklist);
1891
1892   /* place_early() invalidates the outs, place_late needs them. */
1893   compute_irg_outs(irg);
1894
1895   /* Now move the nodes down in the dominator tree. This reduces the
1896      unnecessary executions of the node. */
1897   place_late(worklist);
1898
1899   set_irg_outs_inconsistent(current_ir_graph);
1900   set_irg_loopinfo_inconsistent(current_ir_graph);
1901   del_pdeq(worklist);
1902   current_ir_graph = rem;
1903 }
1904
1905 /**
1906  * Called by walker of remove_critical_cf_edges().
1907  *
1908  * Place an empty block to an edge between a blocks of multiple
1909  * predecessors and a block of multiple successors.
1910  *
1911  * @param n IR node
1912  * @param env Environment of walker. This field is unused and has
1913  *            the value NULL.
1914  */
1915 static void walk_critical_cf_edges(ir_node *n, void *env) {
1916   int arity, i;
1917   ir_node *pre, *block, **in, *jmp;
1918
1919   /* Block has multiple predecessors */
1920   if ((op_Block == get_irn_op(n)) &&
1921       (get_irn_arity(n) > 1)) {
1922     arity = get_irn_arity(n);
1923
1924     if (n == get_irg_end_block(current_ir_graph))
1925       return;  /*  No use to add a block here.      */
1926
1927     for (i=0; i<arity; i++) {
1928       pre = get_irn_n(n, i);
1929       /* Predecessor has multiple successors. Insert new flow edge */
1930       if ((NULL != pre) &&
1931     (op_Proj == get_irn_op(pre)) &&
1932     op_Raise != get_irn_op(skip_Proj(pre))) {
1933
1934     /* set predecessor array for new block */
1935     in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 1);
1936     /* set predecessor of new block */
1937     in[0] = pre;
1938     block = new_Block(1, in);
1939     /* insert new jmp node to new block */
1940     set_cur_block(block);
1941     jmp = new_Jmp();
1942     set_cur_block(n);
1943     /* set successor of new block */
1944     set_irn_n(n, i, jmp);
1945
1946       } /* predecessor has multiple successors */
1947     } /* for all predecessors */
1948   } /* n is a block */
1949 }
1950
1951 void remove_critical_cf_edges(ir_graph *irg) {
1952   if (get_opt_critical_edges())
1953     irg_walk_graph(irg, NULL, walk_critical_cf_edges, NULL);
1954 }