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