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  * 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[5];
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   /* XxMxPxP 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_T_args]         = new_Tuple(get_Call_n_params(call), get_Call_param_arr(call));
992   /* in[pn_Start_P_value_arg_base] = ??? */
993   pre_call = new_Tuple(5, in);
994   post_call = call;
995
996   /* --
997      The new block gets the ins of the old block, pre_call and all its
998      predecessors and all Phi nodes. -- */
999   part_block(pre_call);
1000
1001   /* -- Prepare state for dead node elimination -- */
1002   /* Visited flags in calling irg must be >= flag in called irg.
1003      Else walker and arity computation will not work. */
1004   if (get_irg_visited(current_ir_graph) <= get_irg_visited(called_graph))
1005     set_irg_visited(current_ir_graph, get_irg_visited(called_graph)+1);
1006   if (get_irg_block_visited(current_ir_graph)< get_irg_block_visited(called_graph))
1007     set_irg_block_visited(current_ir_graph, get_irg_block_visited(called_graph));
1008   /* Set pre_call as new Start node in link field of the start node of
1009      calling graph and pre_calls block as new block for the start block
1010      of calling graph.
1011      Further mark these nodes so that they are not visited by the
1012      copying. */
1013   set_irn_link(get_irg_start(called_graph), pre_call);
1014   set_irn_visited(get_irg_start(called_graph), get_irg_visited(current_ir_graph));
1015   set_irn_link(get_irg_start_block(called_graph), get_nodes_block(pre_call));
1016   set_irn_visited(get_irg_start_block(called_graph), get_irg_visited(current_ir_graph));
1017   set_irn_link(get_irg_bad(called_graph), get_irg_bad(current_ir_graph));
1018   set_irn_visited(get_irg_bad(called_graph), get_irg_visited(current_ir_graph));
1019
1020   /* Initialize for compaction of in arrays */
1021   inc_irg_block_visited(current_ir_graph);
1022
1023   /* -- Replicate local entities of the called_graph -- */
1024   /* copy the entities. */
1025   called_frame = get_irg_frame_type(called_graph);
1026   for (i = 0; i < get_class_n_members(called_frame); i++) {
1027     entity *new_ent, *old_ent;
1028     old_ent = get_class_member(called_frame, i);
1029     new_ent = copy_entity_own(old_ent, get_cur_frame_type());
1030     set_entity_link(old_ent, new_ent);
1031   }
1032
1033   /* visited is > than that of called graph.  With this trick visited will
1034      remain unchanged so that an outer walker, e.g., searching the call nodes
1035      to inline, calling this inline will not visit the inlined nodes. */
1036   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
1037
1038   /* -- Performing dead node elimination inlines the graph -- */
1039   /* Copies the nodes to the obstack of current_ir_graph. Updates links to new
1040      entities. */
1041   /* @@@ endless loops are not copied!! -- they should be, I think... */
1042   irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds,
1043            get_irg_frame_type(called_graph));
1044
1045   /* Repair called_graph */
1046   set_irg_visited(called_graph, get_irg_visited(current_ir_graph));
1047   set_irg_block_visited(called_graph, get_irg_block_visited(current_ir_graph));
1048   set_Block_block_visited(get_irg_start_block(called_graph), 0);
1049
1050   /* -- Merge the end of the inlined procedure with the call site -- */
1051   /* We will turn the old Call node into a Tuple with the following
1052      predecessors:
1053      -1:  Block of Tuple.
1054      0: Phi of all Memories of Return statements.
1055      1: Jmp from new Block that merges the control flow from all exception
1056      predecessors of the old end block.
1057      2: Tuple of all arguments.
1058      3: Phi of Exception memories.
1059      In case the old Call directly branches to End on an exception we don't
1060      need the block merging all exceptions nor the Phi of the exception
1061      memories.
1062   */
1063
1064   /* -- Precompute some values -- */
1065   end_bl = get_new_node(get_irg_end_block(called_graph));
1066   end = get_new_node(get_irg_end(called_graph));
1067   arity = get_irn_arity(end_bl);    /* arity = n_exc + n_ret  */
1068   n_res = get_method_n_ress(get_Call_type(call));
1069
1070   res_pred = xmalloc (n_res * sizeof(*res_pred));
1071   cf_pred  = xmalloc (arity * sizeof(*res_pred));
1072
1073   set_irg_current_block(current_ir_graph, post_bl); /* just to make sure */
1074
1075   /* -- archive keepalives -- */
1076   irn_arity = get_irn_arity(end);
1077   for (i = 0; i < irn_arity; i++)
1078     add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
1079
1080   /* The new end node will die.  We need not free as the in array is on the obstack:
1081      copy_node() only generated 'D' arrays. */
1082
1083   /* -- Replace Return nodes by Jump nodes. -- */
1084   n_ret = 0;
1085   for (i = 0; i < arity; i++) {
1086     ir_node *ret;
1087     ret = get_irn_n(end_bl, i);
1088     if (is_Return(ret)) {
1089       cf_pred[n_ret] = new_r_Jmp(current_ir_graph, get_nodes_block(ret));
1090       n_ret++;
1091     }
1092   }
1093   set_irn_in(post_bl, n_ret, cf_pred);
1094
1095   /* -- Build a Tuple for all results of the method.
1096      Add Phi node if there was more than one Return.  -- */
1097   turn_into_tuple(post_call, 4);
1098   /* First the Memory-Phi */
1099   n_ret = 0;
1100   for (i = 0; i < arity; i++) {
1101     ret = get_irn_n(end_bl, i);
1102     if (is_Return(ret)) {
1103       cf_pred[n_ret] = get_Return_mem(ret);
1104       n_ret++;
1105     }
1106   }
1107   phi = new_Phi(n_ret, cf_pred, mode_M);
1108   set_Tuple_pred(call, pn_Call_M_regular, phi);
1109   /* Conserve Phi-list for further inlinings -- but might be optimized */
1110   if (get_nodes_block(phi) == post_bl) {
1111     set_irn_link(phi, get_irn_link(post_bl));
1112     set_irn_link(post_bl, phi);
1113   }
1114   /* Now the real results */
1115   if (n_res > 0) {
1116     for (j = 0; j < n_res; j++) {
1117       n_ret = 0;
1118       for (i = 0; i < arity; i++) {
1119         ret = get_irn_n(end_bl, i);
1120         if (get_irn_op(ret) == op_Return) {
1121           cf_pred[n_ret] = get_Return_res(ret, j);
1122           n_ret++;
1123         }
1124       }
1125       if (n_ret > 0)
1126         phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0]));
1127       else
1128         phi = new_Bad();
1129       res_pred[j] = phi;
1130       /* Conserve Phi-list for further inlinings -- but might be optimized */
1131       if (get_nodes_block(phi) == post_bl) {
1132         set_irn_link(phi, get_irn_link(post_bl));
1133         set_irn_link(post_bl, phi);
1134       }
1135     }
1136     set_Tuple_pred(call, pn_Call_T_result, new_Tuple(n_res, res_pred));
1137   } else {
1138     set_Tuple_pred(call, pn_Call_T_result, new_Bad());
1139   }
1140   /* Finally the exception control flow.
1141      We have two (three) possible situations:
1142      First if the Call branches to an exception handler: We need to add a Phi node to
1143      collect the memory containing the exception objects.  Further we need
1144      to add another block to get a correct representation of this Phi.  To
1145      this block we add a Jmp that resolves into the X output of the Call
1146      when the Call is turned into a tuple.
1147      Second the Call branches to End, the exception is not handled.  Just
1148      add all inlined exception branches to the End node.
1149      Third: there is no Exception edge at all. Handle as case two. */
1150   if (exc_handling == 0) {
1151     n_exc = 0;
1152     for (i = 0; i < arity; i++) {
1153       ir_node *ret;
1154       ret = get_irn_n(end_bl, i);
1155       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
1156         cf_pred[n_exc] = ret;
1157         n_exc++;
1158       }
1159     }
1160     if (n_exc > 0) {
1161       new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
1162       set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
1163       /* The Phi for the memories with the exception objects */
1164       n_exc = 0;
1165       for (i = 0; i < arity; i++) {
1166         ir_node *ret;
1167         ret = skip_Proj(get_irn_n(end_bl, i));
1168         if (is_Call(ret)) {
1169           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 3);
1170           n_exc++;
1171         } else if (is_fragile_op(ret)) {
1172           /* We rely that all cfops have the memory output at the same position. */
1173           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 0);
1174           n_exc++;
1175         } else if (get_irn_op(ret) == op_Raise) {
1176           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 1);
1177           n_exc++;
1178         }
1179       }
1180       set_Tuple_pred(call, pn_Call_M_except, new_Phi(n_exc, cf_pred, mode_M));
1181     } else {
1182       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1183       set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1184     }
1185   } else {
1186     ir_node *main_end_bl;
1187     int main_end_bl_arity;
1188     ir_node **end_preds;
1189
1190     /* assert(exc_handling == 1 || no exceptions. ) */
1191     n_exc = 0;
1192     for (i = 0; i < arity; i++) {
1193       ir_node *ret = get_irn_n(end_bl, i);
1194
1195       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
1196         cf_pred[n_exc] = ret;
1197         n_exc++;
1198       }
1199     }
1200     main_end_bl = get_irg_end_block(current_ir_graph);
1201     main_end_bl_arity = get_irn_arity(main_end_bl);
1202     end_preds =  xmalloc ((n_exc + main_end_bl_arity) * sizeof(*end_preds));
1203
1204     for (i = 0; i < main_end_bl_arity; ++i)
1205       end_preds[i] = get_irn_n(main_end_bl, i);
1206     for (i = 0; i < n_exc; ++i)
1207       end_preds[main_end_bl_arity + i] = cf_pred[i];
1208     set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
1209     set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1210     set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1211     free(end_preds);
1212   }
1213   free(res_pred);
1214   free(cf_pred);
1215
1216 #if 0  /* old. now better, correcter, faster implementation. */
1217   if (n_exc > 0) {
1218     /* -- If the exception control flow from the inlined Call directly
1219        branched to the end block we now have the following control
1220        flow predecessor pattern: ProjX -> Tuple -> Jmp.  We must
1221        remove the Jmp along with it's empty block and add Jmp's
1222        predecessors as predecessors of this end block.  No problem if
1223        there is no exception, because then branches Bad to End which
1224        is fine. --
1225        @@@ can't we know this beforehand: by getting the Proj(1) from
1226        the Call link list and checking whether it goes to Proj. */
1227     /* find the problematic predecessor of the end block. */
1228     end_bl = get_irg_end_block(current_ir_graph);
1229     for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
1230       cf_op = get_Block_cfgpred(end_bl, i);
1231       if (get_irn_op(cf_op) == op_Proj) {
1232         cf_op = get_Proj_pred(cf_op);
1233         if ((get_irn_op(cf_op) == op_Tuple) && (cf_op == call)) {
1234           /*  There are unoptimized tuples from inlineing before when no exc */
1235           assert(get_Proj_proj(get_Block_cfgpred(end_bl, i)) == pn_Call_X_except);
1236           cf_op = get_Tuple_pred(cf_op, pn_Call_X_except);
1237           assert(get_irn_op(cf_op) == op_Jmp);
1238           break;
1239         }
1240       }
1241     }
1242     /* repair */
1243     if (i < get_Block_n_cfgpreds(end_bl)) {
1244       bl = get_nodes_block(cf_op);
1245       arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
1246       cf_pred = xmalloc (arity * sizeof(*cf_pred));
1247       for (j = 0; j < i; j++)
1248         cf_pred[j] = get_Block_cfgpred(end_bl, j);
1249       for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
1250         cf_pred[j] = get_Block_cfgpred(bl, j-i);
1251       for (j = j; j < arity; j++)
1252         cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
1253       set_irn_in(end_bl, arity, cf_pred);
1254       free(cf_pred);
1255       /*  Remove the exception pred from post-call Tuple. */
1256       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1257     }
1258   }
1259 #endif
1260
1261   /* --  Turn CSE back on. -- */
1262   set_optimize(rem_opt);
1263
1264   return 1;
1265 }
1266
1267 /********************************************************************/
1268 /* Apply inlineing to small methods.                                */
1269 /********************************************************************/
1270
1271 /* It makes no sense to inline too many calls in one procedure. Anyways,
1272    I didn't get a version with NEW_ARR_F to run. */
1273 #define MAX_INLINE 1024
1274
1275 /**
1276  * environment for inlining small irgs
1277  */
1278 typedef struct _inline_env_t {
1279   int pos;
1280   ir_node *calls[MAX_INLINE];
1281 } inline_env_t;
1282
1283 /**
1284  * Returns the irg called from a Call node. If the irg is not
1285  * known, NULL is returned.
1286  */
1287 static ir_graph *get_call_called_irg(ir_node *call) {
1288   ir_node *addr;
1289   ir_graph *called_irg = NULL;
1290
1291   assert(is_Call(call));
1292
1293   addr = get_Call_ptr(call);
1294   if ((get_irn_op(addr) == op_SymConst) && (get_SymConst_kind (addr) == symconst_addr_ent)) {
1295     called_irg = get_entity_irg(get_SymConst_entity(addr));
1296   }
1297
1298   return called_irg;
1299 }
1300
1301 static void collect_calls(ir_node *call, void *env) {
1302   ir_node *addr;
1303
1304   if (! is_Call(call)) return;
1305
1306   addr = get_Call_ptr(call);
1307
1308   if (get_irn_op(addr) == op_SymConst) {
1309     if (get_SymConst_kind(addr) == symconst_addr_ent) {
1310       ir_graph *called_irg = get_entity_irg(get_SymConst_entity(addr));
1311       inline_env_t *ienv = (inline_env_t *)env;
1312       if (called_irg && ienv->pos < MAX_INLINE) {
1313         /* The Call node calls a locally defined method.  Remember to inline. */
1314         ienv->calls[ienv->pos++] = call;
1315       }
1316     }
1317   }
1318 }
1319
1320 /**
1321  * Inlines all small methods at call sites where the called address comes
1322  * from a Const node that references the entity representing the called
1323  * method.
1324  * The size argument is a rough measure for the code size of the method:
1325  * Methods where the obstack containing the firm graph is smaller than
1326  * size are inlined.
1327  */
1328 void inline_small_irgs(ir_graph *irg, int size) {
1329   int i;
1330   ir_graph *rem = current_ir_graph;
1331   inline_env_t env /* = {0, NULL}*/;
1332
1333   if (!(get_opt_optimize() && get_opt_inline())) return;
1334
1335   current_ir_graph = irg;
1336   /* Handle graph state */
1337   assert(get_irg_phase_state(current_ir_graph) != phase_building);
1338   free_callee_info(current_ir_graph);
1339
1340   /* Find Call nodes to inline.
1341      (We can not inline during a walk of the graph, as inlineing the same
1342      method several times changes the visited flag of the walked graph:
1343      after the first inlineing visited of the callee equals visited of
1344      the caller.  With the next inlineing both are increased.) */
1345   env.pos = 0;
1346   irg_walk(get_irg_end(irg), NULL, collect_calls, &env);
1347
1348   if ((env.pos > 0) && (env.pos < MAX_INLINE)) {
1349     /* There are calls to inline */
1350     collect_phiprojs(irg);
1351     for (i = 0; i < env.pos; i++) {
1352       ir_graph *callee;
1353       callee = get_entity_irg(get_SymConst_entity(get_Call_ptr(env.calls[i])));
1354       if (((_obstack_memory_used(callee->obst) - (int)obstack_room(callee->obst)) < size) ||
1355         (get_irg_inline_property(callee) == irg_inline_forced)) {
1356         inline_method(env.calls[i], callee);
1357       }
1358     }
1359   }
1360
1361   current_ir_graph = rem;
1362 }
1363
1364 /**
1365  * Environment for inlining irgs.
1366  */
1367 typedef struct {
1368   int n_nodes;       /**< Nodes in graph except Id, Tuple, Proj, Start, End */
1369   int n_nodes_orig;  /**< for statistics */
1370   eset *call_nodes;  /**< All call nodes in this graph */
1371   int n_call_nodes;
1372   int n_call_nodes_orig; /**< for statistics */
1373   int n_callers;   /**< Number of known graphs that call this graphs. */
1374   int n_callers_orig; /**< for statistics */
1375 } inline_irg_env;
1376
1377 /**
1378  * Allocate a new environment for inlining.
1379  */
1380 static inline_irg_env *new_inline_irg_env(void) {
1381   inline_irg_env *env    = xmalloc(sizeof(*env));
1382   env->n_nodes           = -2; /* do not count count Start, End */
1383   env->n_nodes_orig      = -2; /* do not count Start, End */
1384   env->call_nodes        = eset_create();
1385   env->n_call_nodes      = 0;
1386   env->n_call_nodes_orig = 0;
1387   env->n_callers         = 0;
1388   env->n_callers_orig    = 0;
1389   return env;
1390 }
1391
1392 /**
1393  * destroy an environment for inlining.
1394  */
1395 static void free_inline_irg_env(inline_irg_env *env) {
1396   eset_destroy(env->call_nodes);
1397   free(env);
1398 }
1399
1400 /**
1401  * post-walker: collect all calls in the inline-environment
1402  * of a graph and sum some statistics.
1403  */
1404 static void collect_calls2(ir_node *call, void *env) {
1405   inline_irg_env *x = (inline_irg_env *)env;
1406   ir_op *op = get_irn_op(call);
1407   ir_graph *callee;
1408
1409   /* count meaningful nodes in irg */
1410   if (op != op_Proj && op != op_Tuple && op != op_Sync) {
1411     x->n_nodes++;
1412     x->n_nodes_orig++;
1413   }
1414
1415   if (op != op_Call) return;
1416
1417   /* collect all call nodes */
1418   eset_insert(x->call_nodes, call);
1419   x->n_call_nodes++;
1420   x->n_call_nodes_orig++;
1421
1422   /* count all static callers */
1423   callee = get_call_called_irg(call);
1424   if (callee) {
1425     inline_irg_env *callee_env = get_irg_link(callee);
1426     callee_env->n_callers++;
1427     callee_env->n_callers_orig++;
1428   }
1429 }
1430
1431 /**
1432  * Returns TRUE if the number of callers in 0 in the irg's environment,
1433  * hence this irg is a leave.
1434  */
1435 INLINE static int is_leave(ir_graph *irg) {
1436   return (((inline_irg_env *)get_irg_link(irg))->n_call_nodes == 0);
1437 }
1438
1439 /**
1440  * Returns TRUE if the number of callers is smaller size in the irg's environment.
1441  */
1442 INLINE static int is_smaller(ir_graph *callee, int size) {
1443   return (((inline_irg_env *)get_irg_link(callee))->n_nodes < size);
1444 }
1445
1446
1447 /*
1448  * Inlines small leave methods at call sites where the called address comes
1449  * from a Const node that references the entity representing the called
1450  * method.
1451  * The size argument is a rough measure for the code size of the method:
1452  * Methods where the obstack containing the firm graph is smaller than
1453  * size are inlined.
1454  */
1455 void inline_leave_functions(int maxsize, int leavesize, int size) {
1456   inline_irg_env *env;
1457   int i, n_irgs = get_irp_n_irgs();
1458   ir_graph *rem = current_ir_graph;
1459   int did_inline = 1;
1460
1461   if (!(get_opt_optimize() && get_opt_inline())) return;
1462
1463   /* extend all irgs by a temporary data structure for inlining. */
1464   for (i = 0; i < n_irgs; ++i)
1465     set_irg_link(get_irp_irg(i), new_inline_irg_env());
1466
1467   /* Precompute information in temporary data structure. */
1468   for (i = 0; i < n_irgs; ++i) {
1469     current_ir_graph = get_irp_irg(i);
1470     assert(get_irg_phase_state(current_ir_graph) != phase_building);
1471     free_callee_info(current_ir_graph);
1472
1473     irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2,
1474              get_irg_link(current_ir_graph));
1475   }
1476
1477   /* -- and now inline. -- */
1478
1479   /* Inline leaves recursively -- we might construct new leaves. */
1480   while (did_inline) {
1481     did_inline = 0;
1482
1483     for (i = 0; i < n_irgs; ++i) {
1484       ir_node *call;
1485       int phiproj_computed = 0;
1486
1487       current_ir_graph = get_irp_irg(i);
1488       env = (inline_irg_env *)get_irg_link(current_ir_graph);
1489
1490       for (call = eset_first(env->call_nodes); call; call = eset_next(env->call_nodes)) {
1491         ir_graph *callee;
1492
1493         if (get_irn_op(call) == op_Tuple) continue;   /* We already have inlined this call. */
1494         callee = get_call_called_irg(call);
1495
1496         if (env->n_nodes > maxsize) continue; // break;
1497
1498         if (callee && (is_leave(callee) && is_smaller(callee, leavesize))) {
1499           if (!phiproj_computed) {
1500             phiproj_computed = 1;
1501             collect_phiprojs(current_ir_graph);
1502           }
1503           did_inline = inline_method(call, callee);
1504
1505           if (did_inline) {
1506             /* Do some statistics */
1507             inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1508             env->n_call_nodes --;
1509             env->n_nodes += callee_env->n_nodes;
1510             callee_env->n_callers--;
1511           }
1512         }
1513       }
1514     }
1515   }
1516
1517   /* inline other small functions. */
1518   for (i = 0; i < n_irgs; ++i) {
1519     ir_node *call;
1520     eset *walkset;
1521     int phiproj_computed = 0;
1522
1523     current_ir_graph = get_irp_irg(i);
1524     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1525
1526     /* we can not walk and change a set, nor remove from it.
1527        So recompute.*/
1528     walkset = env->call_nodes;
1529     env->call_nodes = eset_create();
1530     for (call = eset_first(walkset); call; call = eset_next(walkset)) {
1531       ir_graph *callee;
1532
1533       if (get_irn_op(call) == op_Tuple) continue;   /* We already inlined. */
1534       callee = get_call_called_irg(call);
1535
1536       if (callee &&
1537           ((is_smaller(callee, size) && (env->n_nodes < maxsize)) ||    /* small function */
1538            (get_irg_inline_property(callee) == irg_inline_forced))) {
1539         if (!phiproj_computed) {
1540             phiproj_computed = 1;
1541             collect_phiprojs(current_ir_graph);
1542         }
1543         if (inline_method(call, callee)) {
1544           inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1545           env->n_call_nodes--;
1546           eset_insert_all(env->call_nodes, callee_env->call_nodes);  /* @@@ ??? This are the wrong nodes !? Not the copied ones. */
1547           env->n_call_nodes += callee_env->n_call_nodes;
1548           env->n_nodes += callee_env->n_nodes;
1549           callee_env->n_callers--;
1550         }
1551       } else {
1552         eset_insert(env->call_nodes, call);
1553       }
1554     }
1555     eset_destroy(walkset);
1556   }
1557
1558   for (i = 0; i < n_irgs; ++i) {
1559     current_ir_graph = get_irp_irg(i);
1560 #if 0
1561     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1562     if ((env->n_call_nodes_orig != env->n_call_nodes) ||
1563         (env->n_callers_orig != env->n_callers))
1564       printf("Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
1565              env->n_nodes_orig, env->n_nodes, env->n_call_nodes_orig, env->n_call_nodes,
1566              env->n_callers_orig, env->n_callers,
1567              get_entity_name(get_irg_entity(current_ir_graph)));
1568 #endif
1569     free_inline_irg_env((inline_irg_env *)get_irg_link(current_ir_graph));
1570   }
1571
1572   current_ir_graph = rem;
1573 }
1574
1575 /*******************************************************************/
1576 /*  Code Placement.  Pins all floating nodes to a block where they */
1577 /*  will be executed only if needed.                               */
1578 /*******************************************************************/
1579
1580 /**
1581  * Returns non-zero, is a block is not reachable from Start.
1582  *
1583  * @param block  the block to test
1584  */
1585 static int
1586 is_Block_unreachable(ir_node *block) {
1587   return is_Block_dead(block) || get_Block_dom_depth(block) < 0;
1588 }
1589
1590 /**
1591  * Find the earliest correct block for N.  --- Place N into the
1592  * same Block as its dominance-deepest Input.
1593  *
1594  * We have to avoid calls to get_nodes_block() here
1595  * because the graph is floating.
1596  *
1597  * move_out_of_loops() expects that place_floats_early() have placed
1598  * all "living" nodes into a living block. That's why we must
1599  * move nodes in dead block with "live" successors into a valid
1600  * block.
1601  * We move them just into the same block as it's successor (or
1602  * in case of a Phi into the effective use block). For Phi successors,
1603  * this may still be a dead block, but then there is no real use, as
1604  * the control flow will be dead later.
1605  */
1606 static void
1607 place_floats_early(ir_node *n, pdeq *worklist)
1608 {
1609   int i, irn_arity;
1610
1611   /* we must not run into an infinite loop */
1612   assert(irn_not_visited(n));
1613   mark_irn_visited(n);
1614
1615   /* Place floating nodes. */
1616   if (get_irn_pinned(n) == op_pin_state_floats) {
1617     ir_node *curr_block = get_irn_n(n, -1);
1618     int in_dead_block   = is_Block_unreachable(curr_block);
1619     int depth           = 0;
1620     ir_node *b          = NULL;   /* The block to place this node in */
1621
1622     assert(get_irn_op(n) != op_Block);
1623
1624     if ((get_irn_op(n) == op_Const) ||
1625         (get_irn_op(n) == op_SymConst) ||
1626         (is_Bad(n)) ||
1627         (get_irn_op(n) == op_Unknown)) {
1628       /* These nodes will not be placed by the loop below. */
1629       b = get_irg_start_block(current_ir_graph);
1630       depth = 1;
1631     }
1632
1633     /* find the block for this node. */
1634     irn_arity = get_irn_arity(n);
1635     for (i = 0; i < irn_arity; i++) {
1636       ir_node *pred = get_irn_n(n, i);
1637       ir_node *pred_block;
1638
1639       if ((irn_not_visited(pred))
1640          && (get_irn_pinned(pred) == op_pin_state_floats)) {
1641
1642         /*
1643          * If the current node is NOT in a dead block, but one of its
1644          * predecessors is, we must move the predecessor to a live block.
1645          * Such thing can happen, if global CSE chose a node from a dead block.
1646          * We move it simple to our block.
1647          * Note that neither Phi nor End nodes are floating, so we don't
1648          * need to handle them here.
1649          */
1650         if (! in_dead_block) {
1651           if (get_irn_pinned(pred) == op_pin_state_floats &&
1652               is_Block_unreachable(get_irn_n(pred, -1)))
1653             set_nodes_block(pred, curr_block);
1654         }
1655         place_floats_early(pred, worklist);
1656       }
1657
1658       /*
1659        * A node in the Bad block must stay in the bad block,
1660        * so don't compute a new block for it.
1661        */
1662       if (in_dead_block)
1663         continue;
1664
1665       /* Because all loops contain at least one op_pin_state_pinned node, now all
1666          our inputs are either op_pin_state_pinned or place_early() has already
1667          been finished on them.  We do not have any unfinished inputs!  */
1668       pred_block = get_irn_n(pred, -1);
1669       if ((!is_Block_dead(pred_block)) &&
1670           (get_Block_dom_depth(pred_block) > depth)) {
1671         b = pred_block;
1672         depth = get_Block_dom_depth(pred_block);
1673       }
1674       /* Avoid that the node is placed in the Start block */
1675       if ((depth == 1) && (get_Block_dom_depth(get_irn_n(n, -1)) > 1)) {
1676         b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
1677         assert(b != get_irg_start_block(current_ir_graph));
1678         depth = 2;
1679       }
1680     }
1681     if (b)
1682       set_nodes_block(n, b);
1683   }
1684
1685   /*
1686    * Add predecessors of non floating nodes and non-floating predecessors
1687    * of floating nodes to worklist and fix their blocks if the are in dead block.
1688    */
1689   irn_arity = get_irn_arity(n);
1690
1691   if (get_irn_op(n) == op_End) {
1692     /*
1693      * Simplest case: End node. Predecessors are keep-alives,
1694      * no need to move out of dead block.
1695      */
1696     for (i = -1; i < irn_arity; ++i) {
1697       ir_node *pred = get_irn_n(n, i);
1698       if (irn_not_visited(pred))
1699         pdeq_putr(worklist, pred);
1700     }
1701   }
1702   else if (is_Block(n)) {
1703     /*
1704      * Blocks: Predecessors are control flow, no need to move
1705      * them out of dead block.
1706      */
1707     for (i = irn_arity - 1; i >= 0; --i) {
1708       ir_node *pred = get_irn_n(n, i);
1709       if (irn_not_visited(pred))
1710         pdeq_putr(worklist, pred);
1711     }
1712   }
1713   else if (is_Phi(n)) {
1714     ir_node *pred;
1715     ir_node *curr_block = get_irn_n(n, -1);
1716     int in_dead_block   = is_Block_unreachable(curr_block);
1717
1718     /*
1719      * Phi nodes: move nodes from dead blocks into the effective use
1720      * of the Phi-input if the Phi is not in a bad block.
1721      */
1722     pred = get_irn_n(n, -1);
1723     if (irn_not_visited(pred))
1724       pdeq_putr(worklist, pred);
1725
1726     for (i = irn_arity - 1; i >= 0; --i) {
1727       ir_node *pred = get_irn_n(n, i);
1728
1729       if (irn_not_visited(pred)) {
1730         if (! in_dead_block &&
1731             get_irn_pinned(pred) == op_pin_state_floats &&
1732             is_Block_unreachable(get_irn_n(pred, -1))) {
1733           set_nodes_block(pred, get_Block_cfgpred_block(curr_block, i));
1734         }
1735         pdeq_putr(worklist, pred);
1736       }
1737     }
1738   }
1739   else {
1740     ir_node *pred;
1741     ir_node *curr_block = get_irn_n(n, -1);
1742     int in_dead_block   = is_Block_unreachable(curr_block);
1743
1744     /*
1745      * All other nodes: move nodes from dead blocks into the same block.
1746      */
1747     pred = get_irn_n(n, -1);
1748     if (irn_not_visited(pred))
1749       pdeq_putr(worklist, pred);
1750
1751     for (i = irn_arity - 1; i >= 0; --i) {
1752       ir_node *pred = get_irn_n(n, i);
1753
1754       if (irn_not_visited(pred)) {
1755         if (! in_dead_block &&
1756             get_irn_pinned(pred) == op_pin_state_floats &&
1757             is_Block_unreachable(get_irn_n(pred, -1))) {
1758           set_nodes_block(pred, curr_block);
1759         }
1760         pdeq_putr(worklist, pred);
1761       }
1762     }
1763   }
1764 }
1765
1766 /**
1767  * Floating nodes form subgraphs that begin at nodes as Const, Load,
1768  * Start, Call and that end at op_pin_state_pinned nodes as Store, Call.  Place_early
1769  * places all floating nodes reachable from its argument through floating
1770  * nodes and adds all beginnings at op_pin_state_pinned nodes to the worklist.
1771  */
1772 static INLINE void place_early(pdeq *worklist) {
1773   assert(worklist);
1774   inc_irg_visited(current_ir_graph);
1775
1776   /* this inits the worklist */
1777   place_floats_early(get_irg_end(current_ir_graph), worklist);
1778
1779   /* Work the content of the worklist. */
1780   while (!pdeq_empty(worklist)) {
1781     ir_node *n = pdeq_getl(worklist);
1782     if (irn_not_visited(n))
1783       place_floats_early(n, worklist);
1784   }
1785
1786   set_irg_outs_inconsistent(current_ir_graph);
1787   set_irg_pinned(current_ir_graph, op_pin_state_pinned);
1788 }
1789
1790 /**
1791  * Compute the deepest common ancestor of block and dca.
1792  */
1793 static ir_node *calc_dca(ir_node *dca, ir_node *block)
1794 {
1795   assert(block);
1796
1797   /* we do not want to place nodes in dead blocks */
1798   if (is_Block_dead(block))
1799     return dca;
1800
1801   /* We found a first legal placement. */
1802   if (!dca) return block;
1803
1804   /* Find a placement that is dominates both, dca and block. */
1805   while (get_Block_dom_depth(block) > get_Block_dom_depth(dca))
1806     block = get_Block_idom(block);
1807
1808   while (get_Block_dom_depth(dca) > get_Block_dom_depth(block)) {
1809     dca = get_Block_idom(dca);
1810   }
1811
1812   while (block != dca)
1813     { block = get_Block_idom(block); dca = get_Block_idom(dca); }
1814
1815   return dca;
1816 }
1817
1818 /** Deepest common dominance ancestor of DCA and CONSUMER of PRODUCER.
1819  * I.e., DCA is the block where we might place PRODUCER.
1820  * A data flow edge points from producer to consumer.
1821  */
1822 static ir_node *
1823 consumer_dom_dca(ir_node *dca, ir_node *consumer, ir_node *producer)
1824 {
1825   ir_node *block = NULL;
1826
1827   /* Compute the latest block into which we can place a node so that it is
1828      before consumer. */
1829   if (get_irn_op(consumer) == op_Phi) {
1830     /* our consumer is a Phi-node, the effective use is in all those
1831        blocks through which the Phi-node reaches producer */
1832     int i, irn_arity;
1833     ir_node *phi_block = get_nodes_block(consumer);
1834     irn_arity = get_irn_arity(consumer);
1835
1836     for (i = 0;  i < irn_arity; i++) {
1837       if (get_irn_n(consumer, i) == producer) {
1838         ir_node *new_block = get_nodes_block(get_Block_cfgpred(phi_block, i));
1839
1840         if (! is_Block_unreachable(new_block))
1841           block = calc_dca(block, new_block);
1842       }
1843     }
1844
1845     if (! block)
1846       block = get_irn_n(producer, -1);
1847   }
1848   else {
1849     assert(is_no_Block(consumer));
1850     block = get_nodes_block(consumer);
1851   }
1852
1853   /* Compute the deepest common ancestor of block and dca. */
1854   return calc_dca(dca, block);
1855 }
1856
1857 /* FIXME: the name clashes here with the function from ana/field_temperature.c
1858  * please rename. */
1859 static INLINE int get_irn_loop_depth(ir_node *n) {
1860   return get_loop_depth(get_irn_loop(n));
1861 }
1862
1863 /**
1864  * Move n to a block with less loop depth than it's current block. The
1865  * new block must be dominated by early.
1866  *
1867  * @param n      the node that should be moved
1868  * @param early  the earliest block we can n move to
1869  */
1870 static void
1871 move_out_of_loops (ir_node *n, ir_node *early)
1872 {
1873   ir_node *best, *dca;
1874   assert(n && early);
1875
1876
1877   /* Find the region deepest in the dominator tree dominating
1878      dca with the least loop nesting depth, but still dominated
1879      by our early placement. */
1880   dca = get_nodes_block(n);
1881
1882   best = dca;
1883   while (dca != early) {
1884     dca = get_Block_idom(dca);
1885     if (!dca || is_Bad(dca)) break; /* may be Bad if not reachable from Start */
1886     if (get_irn_loop_depth(dca) < get_irn_loop_depth(best)) {
1887       best = dca;
1888     }
1889   }
1890   if (best != get_nodes_block(n)) {
1891     /* debug output
1892     printf("Moving out of loop: "); DDMN(n);
1893     printf(" Outermost block: "); DDMN(early);
1894     printf(" Best block: "); DDMN(best);
1895     printf(" Innermost block: "); DDMN(get_nodes_block(n));
1896     */
1897     set_nodes_block(n, best);
1898   }
1899 }
1900
1901 /**
1902  * Find the latest legal block for N and place N into the
1903  * `optimal' Block between the latest and earliest legal block.
1904  * The `optimal' block is the dominance-deepest block of those
1905  * with the least loop-nesting-depth.  This places N out of as many
1906  * loops as possible and then makes it as control dependent as
1907  * possible.
1908  */
1909 static void
1910 place_floats_late(ir_node *n, pdeq *worklist)
1911 {
1912   int i;
1913   ir_node *early_blk;
1914
1915   assert(irn_not_visited(n)); /* no multiple placement */
1916
1917   mark_irn_visited(n);
1918
1919   /* no need to place block nodes, control nodes are already placed. */
1920   if ((get_irn_op(n) != op_Block) &&
1921       (!is_cfop(n)) &&
1922       (get_irn_mode(n) != mode_X)) {
1923     /* Remember the early_blk placement of this block to move it
1924        out of loop no further than the early_blk placement. */
1925     early_blk = get_irn_n(n, -1);
1926
1927     /*
1928      * BEWARE: Here we also get code, that is live, but
1929      * was in a dead block.  If the node is life, but because
1930      * of CSE in a dead block, we still might need it.
1931      */
1932
1933     /* Assure that our users are all placed, except the Phi-nodes.
1934        --- Each data flow cycle contains at least one Phi-node.  We
1935        have to break the `user has to be placed before the
1936        producer' dependence cycle and the Phi-nodes are the
1937        place to do so, because we need to base our placement on the
1938        final region of our users, which is OK with Phi-nodes, as they
1939        are op_pin_state_pinned, and they never have to be placed after a
1940        producer of one of their inputs in the same block anyway. */
1941     for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
1942       ir_node *succ = get_irn_out(n, i);
1943       if (irn_not_visited(succ) && (get_irn_op(succ) != op_Phi))
1944         place_floats_late(succ, worklist);
1945     }
1946
1947     if (! is_Block_dead(early_blk)) {
1948       /* do only move things that where not dead */
1949
1950       /* We have to determine the final block of this node... except for
1951          constants. */
1952       if ((get_irn_pinned(n) == op_pin_state_floats) &&
1953           (get_irn_op(n) != op_Const) &&
1954           (get_irn_op(n) != op_SymConst)) {
1955         ir_node *dca = NULL;  /* deepest common ancestor in the
1956                      dominator tree of all nodes'
1957                      blocks depending on us; our final
1958                      placement has to dominate DCA. */
1959         for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
1960           ir_node *succ = get_irn_out(n, i);
1961           ir_node *succ_blk;
1962
1963           if (get_irn_op(succ) == op_End) {
1964             /*
1965              * This consumer is the End node, a keep alive edge.
1966              * This is not a real consumer, so we ignore it
1967              */
1968             continue;
1969           }
1970
1971           /* ignore if succ is in dead code */
1972           succ_blk = get_irn_n(succ, -1);
1973           if (is_Block_unreachable(succ_blk))
1974             continue;
1975           dca = consumer_dom_dca(dca, succ, n);
1976         }
1977         if (dca) {
1978           set_nodes_block(n, dca);
1979           move_out_of_loops(n, early_blk);
1980         }
1981       }
1982     }
1983   }
1984
1985   /* Add predecessors of all non-floating nodes on list. (Those of floating
1986      nodes are placed already and therefore are marked.)  */
1987   for (i = 0; i < get_irn_n_outs(n); i++) {
1988     ir_node *succ = get_irn_out(n, i);
1989     if (irn_not_visited(get_irn_out(n, i))) {
1990       pdeq_putr(worklist, succ);
1991     }
1992   }
1993 }
1994
1995 static INLINE void place_late(pdeq *worklist) {
1996   assert(worklist);
1997   inc_irg_visited(current_ir_graph);
1998
1999   /* This fills the worklist initially. */
2000   place_floats_late(get_irg_start_block(current_ir_graph), worklist);
2001
2002   /* And now empty the worklist again... */
2003   while (!pdeq_empty(worklist)) {
2004     ir_node *n = pdeq_getl(worklist);
2005     if (irn_not_visited(n))
2006       place_floats_late(n, worklist);
2007   }
2008 }
2009
2010 void place_code(ir_graph *irg) {
2011   pdeq *worklist;
2012   ir_graph *rem = current_ir_graph;
2013
2014   current_ir_graph = irg;
2015
2016   if (!(get_opt_optimize() && get_opt_global_cse())) return;
2017
2018   /* Handle graph state */
2019   assert(get_irg_phase_state(irg) != phase_building);
2020   assure_doms(irg);
2021
2022   if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) {
2023     free_loop_information(irg);
2024     construct_backedges(irg);
2025   }
2026
2027   /* Place all floating nodes as early as possible. This guarantees
2028      a legal code placement. */
2029   worklist = new_pdeq();
2030   place_early(worklist);
2031
2032   /* place_early() invalidates the outs, place_late needs them. */
2033   compute_irg_outs(irg);
2034
2035   /* Now move the nodes down in the dominator tree. This reduces the
2036      unnecessary executions of the node. */
2037   place_late(worklist);
2038
2039   set_irg_outs_inconsistent(current_ir_graph);
2040   set_irg_loopinfo_inconsistent(current_ir_graph);
2041   del_pdeq(worklist);
2042   current_ir_graph = rem;
2043 }
2044
2045 /**
2046  * Called by walker of remove_critical_cf_edges().
2047  *
2048  * Place an empty block to an edge between a blocks of multiple
2049  * predecessors and a block of multiple successors.
2050  *
2051  * @param n   IR node
2052  * @param env Environment of walker. The changed field.
2053  */
2054 static void walk_critical_cf_edges(ir_node *n, void *env) {
2055   int arity, i;
2056   ir_node *pre, *block, *jmp;
2057   int *changed = env;
2058
2059   /* Block has multiple predecessors */
2060   if (is_Block(n) && (get_irn_arity(n) > 1)) {
2061     if (n == get_irg_end_block(current_ir_graph))
2062       return;  /*  No use to add a block here.      */
2063
2064     arity = get_irn_arity(n);
2065     for (i=0; i<arity; i++) {
2066       pre = get_irn_n(n, i);
2067       /* Predecessor has multiple successors. Insert new control flow edge. */
2068       if (op_Raise != get_irn_op(skip_Proj(pre))) {
2069         /* set predecessor of new block */
2070         block = new_Block(1, &pre);
2071         /* insert new jmp node to new block */
2072         set_cur_block(block);
2073         jmp = new_Jmp();
2074         set_cur_block(n);
2075         /* set successor of new block */
2076         set_irn_n(n, i, jmp);
2077         *changed = 1;
2078       } /* predecessor has multiple successors */
2079     } /* for all predecessors */
2080   } /* n is a block */
2081 }
2082
2083 void remove_critical_cf_edges(ir_graph *irg) {
2084   int changed = 0;
2085   irg_walk_graph(irg, NULL, walk_critical_cf_edges, &changed);
2086
2087   if (changed) {
2088     /* control flow changed */
2089     set_irg_outs_inconsistent(irg);
2090     set_irg_extblk_inconsistent(irg);
2091     set_irg_doms_inconsistent(current_ir_graph);
2092     set_irg_loopinfo_inconsistent(current_ir_graph);
2093   }
2094
2095 }