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