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