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