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