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