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