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