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