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