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