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