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