af55fb5ce1662a209e25a8d3fae878cdaa2a72f4
[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     if (get_SymConst_kind(addr) == symconst_addr_ent) {
1093       ir_graph *called_irg = get_entity_irg(get_SymConst_entity(addr));
1094       inline_env_t *ienv = (inline_env_t *)env;
1095       if (called_irg && ienv->pos < MAX_INLINE) {
1096         /* The Call node calls a locally defined method.  Remember to inline. */
1097         ienv->calls[ienv->pos++] = call;
1098       }
1099     }
1100   }
1101 }
1102
1103 /**
1104  * Inlines all small methods at call sites where the called address comes
1105  * from a Const node that references the entity representing the called
1106  * method.
1107  * The size argument is a rough measure for the code size of the method:
1108  * Methods where the obstack containing the firm graph is smaller than
1109  * size are inlined.
1110  */
1111 void inline_small_irgs(ir_graph *irg, int size) {
1112   int i;
1113   ir_graph *rem = current_ir_graph;
1114   inline_env_t env /* = {0, NULL}*/;
1115
1116   if (!(get_opt_optimize() && get_opt_inline())) return;
1117
1118   current_ir_graph = irg;
1119   /* Handle graph state */
1120   assert(get_irg_phase_state(current_ir_graph) != phase_building);
1121   free_callee_info(current_ir_graph);
1122
1123   /* Find Call nodes to inline.
1124      (We can not inline during a walk of the graph, as inlineing the same
1125      method several times changes the visited flag of the walked graph:
1126      after the first inlineing visited of the callee equals visited of
1127      the caller.  With the next inlineing both are increased.) */
1128   env.pos = 0;
1129   irg_walk(get_irg_end(irg), NULL, collect_calls, &env);
1130
1131   if ((env.pos > 0) && (env.pos < MAX_INLINE)) {
1132     /* There are calls to inline */
1133     collect_phiprojs(irg);
1134     for (i = 0; i < env.pos; i++) {
1135       ir_graph *callee;
1136       //tv = get_Const_tarval(get_Call_ptr(env.calls[i]));
1137       //      callee = get_entity_irg(get_tarval_entity(tv));
1138       callee = get_entity_irg(get_SymConst_entity(get_Call_ptr(env.calls[i])));
1139       if (((_obstack_memory_used(callee->obst) - obstack_room(callee->obst)) < size) ||
1140         (get_irg_inline_property(callee) == irg_inline_forced)) {
1141         inline_method(env.calls[i], callee);
1142       }
1143     }
1144   }
1145
1146   current_ir_graph = rem;
1147 }
1148
1149 /**
1150  * Environment for inlining irgs.
1151  */
1152 typedef struct {
1153   int n_nodes;       /**< Nodes in graph except Id, Tuple, Proj, Start, End */
1154   int n_nodes_orig;  /**< for statistics */
1155   eset *call_nodes;  /**< All call nodes in this graph */
1156   int n_call_nodes;
1157   int n_call_nodes_orig; /**< for statistics */
1158   int n_callers;   /**< Number of known graphs that call this graphs. */
1159   int n_callers_orig; /**< for statistics */
1160 } inline_irg_env;
1161
1162 static inline_irg_env *new_inline_irg_env(void) {
1163   inline_irg_env *env = malloc(sizeof(inline_irg_env));
1164   env->n_nodes = -2; /* uncount Start, End */
1165   env->n_nodes_orig = -2; /* uncount Start, End */
1166   env->call_nodes = eset_create();
1167   env->n_call_nodes = 0;
1168   env->n_call_nodes_orig = 0;
1169   env->n_callers = 0;
1170   env->n_callers_orig = 0;
1171   return env;
1172 }
1173
1174 static void free_inline_irg_env(inline_irg_env *env) {
1175   eset_destroy(env->call_nodes);
1176   free(env);
1177 }
1178
1179 static void collect_calls2(ir_node *call, void *env) {
1180   inline_irg_env *x = (inline_irg_env *)env;
1181   ir_op *op = get_irn_op(call);
1182   ir_graph *callee;
1183
1184   /* count nodes in irg */
1185   if (op != op_Proj && op != op_Tuple && op != op_Sync) {
1186     x->n_nodes++;
1187     x->n_nodes_orig++;
1188   }
1189
1190   if (op != op_Call) return;
1191
1192   /* collect all call nodes */
1193   eset_insert(x->call_nodes, (void *)call);
1194   x->n_call_nodes++;
1195   x->n_call_nodes_orig++;
1196
1197   /* count all static callers */
1198   callee = get_call_called_irg(call);
1199   if (callee) {
1200     ((inline_irg_env *)get_irg_link(callee))->n_callers++;
1201     ((inline_irg_env *)get_irg_link(callee))->n_callers_orig++;
1202   }
1203 }
1204
1205 INLINE static int is_leave(ir_graph *irg) {
1206   return (((inline_irg_env *)get_irg_link(irg))->n_call_nodes == 0);
1207 }
1208
1209 INLINE static int is_smaller(ir_graph *callee, int size) {
1210   return (((inline_irg_env *)get_irg_link(callee))->n_nodes < size);
1211 }
1212
1213
1214 /*
1215  * Inlines small leave methods at call sites where the called address comes
1216  * from a Const node that references the entity representing the called
1217  * method.
1218  * The size argument is a rough measure for the code size of the method:
1219  * Methods where the obstack containing the firm graph is smaller than
1220  * size are inlined.
1221  */
1222 void inline_leave_functions(int maxsize, int leavesize, int size) {
1223   inline_irg_env *env;
1224   int i, n_irgs = get_irp_n_irgs();
1225   ir_graph *rem = current_ir_graph;
1226   int did_inline = 1;
1227
1228   if (!(get_opt_optimize() && get_opt_inline())) return;
1229
1230   /* extend all irgs by a temporary data structure for inlineing. */
1231   for (i = 0; i < n_irgs; ++i)
1232     set_irg_link(get_irp_irg(i), new_inline_irg_env());
1233
1234   /* Precompute information in temporary data structure. */
1235   for (i = 0; i < n_irgs; ++i) {
1236     current_ir_graph = get_irp_irg(i);
1237     assert(get_irg_phase_state(current_ir_graph) != phase_building);
1238     free_callee_info(current_ir_graph);
1239
1240     irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2,
1241          get_irg_link(current_ir_graph));
1242   }
1243
1244   /* and now inline.
1245      Inline leaves recursively -- we might construct new leaves. */
1246   /* int itercnt = 1; */
1247   while (did_inline) {
1248     /* printf("iteration %d\n", itercnt++); */
1249     did_inline = 0;
1250     for (i = 0; i < n_irgs; ++i) {
1251       ir_node *call;
1252       eset *walkset;
1253       int phiproj_computed = 0;
1254
1255       current_ir_graph = get_irp_irg(i);
1256       env = (inline_irg_env *)get_irg_link(current_ir_graph);
1257
1258       /* we can not walk and change a set, nor remove from it.
1259       So recompute.*/
1260       walkset = env->call_nodes;
1261       env->call_nodes = eset_create();
1262       for (call = eset_first(walkset); call; call = eset_next(walkset)) {
1263         inline_irg_env *callee_env;
1264         ir_graph *callee = get_call_called_irg(call);
1265
1266         if (env->n_nodes > maxsize) break;
1267         if (callee &&
1268         ((is_leave(callee) && is_smaller(callee, leavesize)) ||
1269          (get_irg_inline_property(callee) == irg_inline_forced))) {
1270           if (!phiproj_computed) {
1271             phiproj_computed = 1;
1272             collect_phiprojs(current_ir_graph);
1273           }
1274           callee_env = (inline_irg_env *)get_irg_link(callee);
1275 /*         printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)), */
1276 /*         get_entity_name(get_irg_entity(callee))); */
1277           if (inline_method(call, callee)) {
1278             did_inline = 1;
1279         env->n_call_nodes--;
1280         eset_insert_all(env->call_nodes, callee_env->call_nodes);
1281         env->n_call_nodes += callee_env->n_call_nodes;
1282         env->n_nodes += callee_env->n_nodes;
1283         callee_env->n_callers--;
1284       }
1285         } else {
1286           eset_insert(env->call_nodes, call);
1287         }
1288       }
1289       eset_destroy(walkset);
1290     }
1291   }
1292
1293   /* printf("Non leaves\n"); */
1294   /* inline other small functions. */
1295   for (i = 0; i < n_irgs; ++i) {
1296     ir_node *call;
1297     eset *walkset;
1298     int phiproj_computed = 0;
1299
1300     current_ir_graph = get_irp_irg(i);
1301     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1302
1303     /* we can not walk and change a set, nor remove from it.
1304        So recompute.*/
1305     walkset = env->call_nodes;
1306     env->call_nodes = eset_create();
1307     for (call = eset_first(walkset); call; call = eset_next(walkset)) {
1308       inline_irg_env *callee_env;
1309       ir_graph *callee = get_call_called_irg(call);
1310
1311       if (env->n_nodes > maxsize) break;
1312       if (callee && is_smaller(callee, size)) {
1313         if (!phiproj_computed) {
1314             phiproj_computed = 1;
1315             collect_phiprojs(current_ir_graph);
1316         }
1317         callee_env = (inline_irg_env *)get_irg_link(callee);
1318 /*       printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)), */
1319 /*       get_entity_name(get_irg_entity(callee))); */
1320         if (inline_method(call, callee)) {
1321       did_inline = 1;
1322       env->n_call_nodes--;
1323       eset_insert_all(env->call_nodes, callee_env->call_nodes);
1324       env->n_call_nodes += callee_env->n_call_nodes;
1325       env->n_nodes += callee_env->n_nodes;
1326       callee_env->n_callers--;
1327     }
1328       } else {
1329         eset_insert(env->call_nodes, call);
1330       }
1331     }
1332     eset_destroy(walkset);
1333   }
1334
1335   for (i = 0; i < n_irgs; ++i) {
1336     current_ir_graph = get_irp_irg(i);
1337 #if 0
1338     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1339     if ((env->n_call_nodes_orig != env->n_call_nodes) ||
1340     (env->n_callers_orig != env->n_callers))
1341       printf("Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
1342          env->n_nodes_orig, env->n_nodes, env->n_call_nodes_orig, env->n_call_nodes,
1343          env->n_callers_orig, env->n_callers,
1344          get_entity_name(get_irg_entity(current_ir_graph)));
1345 #endif
1346     free_inline_irg_env((inline_irg_env *)get_irg_link(current_ir_graph));
1347   }
1348
1349   current_ir_graph = rem;
1350 }
1351
1352 /*******************************************************************/
1353 /*  Code Placement.  Pins all floating nodes to a block where they */
1354 /*  will be executed only if needed.                               */
1355 /*******************************************************************/
1356
1357 /**
1358  * Find the earliest correct block for N.  --- Place N into the
1359  * same Block as its dominance-deepest Input.
1360  */
1361 static void
1362 place_floats_early(ir_node *n, pdeq *worklist)
1363 {
1364   int i, start, irn_arity;
1365
1366   /* we must not run into an infinite loop */
1367   assert (irn_not_visited(n));
1368   mark_irn_visited(n);
1369
1370   /* Place floating nodes. */
1371   if (get_op_pinned(get_irn_op(n)) == op_pin_state_floats) {
1372     int depth         = 0;
1373     ir_node *b        = new_Bad();   /* The block to place this node in */
1374     int bad_recursion = is_Bad(get_nodes_block(n));
1375
1376     assert(get_irn_op(n) != op_Block);
1377
1378     if ((get_irn_op(n) == op_Const) ||
1379     (get_irn_op(n) == op_SymConst) ||
1380     (is_Bad(n)) ||
1381     (get_irn_op(n) == op_Unknown)) {
1382       /* These nodes will not be placed by the loop below. */
1383       b = get_irg_start_block(current_ir_graph);
1384       depth = 1;
1385     }
1386
1387     /* find the block for this node. */
1388     irn_arity = get_irn_arity(n);
1389     for (i = 0; i < irn_arity; i++) {
1390       ir_node *dep = get_irn_n(n, i);
1391       ir_node *dep_block;
1392
1393       if ((irn_not_visited(dep))
1394      && (get_op_pinned(get_irn_op(dep)) == op_pin_state_floats)) {
1395     place_floats_early(dep, worklist);
1396       }
1397
1398       /*
1399        * A node in the Bad block must stay in the bad block,
1400        * so don't compute a new block for it.
1401        */
1402       if (bad_recursion)
1403         continue;
1404
1405       /* Because all loops contain at least one op_pin_state_pinned node, now all
1406          our inputs are either op_pin_state_pinned or place_early has already
1407          been finished on them.  We do not have any unfinished inputs!  */
1408       dep_block = get_nodes_block(dep);
1409       if ((!is_Bad(dep_block)) &&
1410       (get_Block_dom_depth(dep_block) > depth)) {
1411     b = dep_block;
1412     depth = get_Block_dom_depth(dep_block);
1413       }
1414       /* Avoid that the node is placed in the Start block */
1415       if ((depth == 1) && (get_Block_dom_depth(get_nodes_block(n)) > 1)) {
1416     b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
1417     assert(b != get_irg_start_block(current_ir_graph));
1418     depth = 2;
1419       }
1420     }
1421     set_nodes_block(n, b);
1422   }
1423
1424   /* Add predecessors of non floating nodes on worklist. */
1425   start = (get_irn_op(n) == op_Block) ? 0 : -1;
1426   irn_arity = get_irn_arity(n);
1427   for (i = start; i < irn_arity; i++) {
1428     ir_node *pred = get_irn_n(n, i);
1429     if (irn_not_visited(pred)) {
1430       pdeq_putr (worklist, pred);
1431     }
1432   }
1433 }
1434
1435 /**
1436  * Floating nodes form subgraphs that begin at nodes as Const, Load,
1437  * Start, Call and that end at op_pin_state_pinned nodes as Store, Call.  Place_early
1438  * places all floating nodes reachable from its argument through floating
1439  * nodes and adds all beginnings at op_pin_state_pinned nodes to the worklist.
1440  */
1441 static INLINE void place_early(pdeq* worklist) {
1442   assert(worklist);
1443   inc_irg_visited(current_ir_graph);
1444
1445   /* this inits the worklist */
1446   place_floats_early(get_irg_end(current_ir_graph), worklist);
1447
1448   /* Work the content of the worklist. */
1449   while (!pdeq_empty (worklist)) {
1450     ir_node *n = pdeq_getl (worklist);
1451     if (irn_not_visited(n)) place_floats_early(n, worklist);
1452   }
1453
1454   set_irg_outs_inconsistent(current_ir_graph);
1455   current_ir_graph->op_pin_state_pinned = op_pin_state_pinned;
1456 }
1457
1458
1459 /** deepest common dominance ancestor of DCA and CONSUMER of PRODUCER. */
1460 static ir_node *
1461 consumer_dom_dca (ir_node *dca, ir_node *consumer, ir_node *producer)
1462 {
1463   ir_node *block = NULL;
1464
1465   /* Compute the latest block into which we can place a node so that it is
1466      before consumer. */
1467   if (get_irn_op(consumer) == op_Phi) {
1468     /* our consumer is a Phi-node, the effective use is in all those
1469        blocks through which the Phi-node reaches producer */
1470     int i, irn_arity;
1471     ir_node *phi_block = get_nodes_block(consumer);
1472     irn_arity = get_irn_arity(consumer);
1473     for (i = 0;  i < irn_arity; i++) {
1474       if (get_irn_n(consumer, i) == producer) {
1475     block = get_nodes_block(get_Block_cfgpred(phi_block, i));
1476       }
1477     }
1478   } else {
1479     assert(is_no_Block(consumer));
1480     block = get_nodes_block(consumer);
1481   }
1482
1483   /* Compute the deepest common ancestor of block and dca. */
1484   assert(block);
1485   if (!dca) return block;
1486   while (get_Block_dom_depth(block) > get_Block_dom_depth(dca))
1487     block = get_Block_idom(block);
1488   while (get_Block_dom_depth(dca) > get_Block_dom_depth(block))
1489     dca = get_Block_idom(dca);
1490   while (block != dca)
1491     { block = get_Block_idom(block); dca = get_Block_idom(dca); }
1492
1493   return dca;
1494 }
1495
1496 static INLINE int get_irn_loop_depth(ir_node *n) {
1497   return get_loop_depth(get_irn_loop(n));
1498 }
1499
1500 /**
1501  * Move n to a block with less loop depth than it's current block. The
1502  * new block must be dominated by early.
1503  */
1504 static void
1505 move_out_of_loops (ir_node *n, ir_node *early)
1506 {
1507   ir_node *best, *dca;
1508   assert(n && early);
1509
1510
1511   /* Find the region deepest in the dominator tree dominating
1512      dca with the least loop nesting depth, but still dominated
1513      by our early placement. */
1514   dca = get_nodes_block(n);
1515   best = dca;
1516   while (dca != early) {
1517     dca = get_Block_idom(dca);
1518     if (!dca) break; /* should we put assert(dca)? */
1519     if (get_irn_loop_depth(dca) < get_irn_loop_depth(best)) {
1520       best = dca;
1521     }
1522   }
1523   if (best != get_nodes_block(n)) {
1524     /* debug output
1525     printf("Moving out of loop: "); DDMN(n);
1526     printf(" Outermost block: "); DDMN(early);
1527     printf(" Best block: "); DDMN(best);
1528     printf(" Innermost block: "); DDMN(get_nodes_block(n));
1529     */
1530     set_nodes_block(n, best);
1531   }
1532 }
1533
1534 /**
1535  * Find the latest legal block for N and place N into the
1536  * `optimal' Block between the latest and earliest legal block.
1537  * The `optimal' block is the dominance-deepest block of those
1538  * with the least loop-nesting-depth.  This places N out of as many
1539  * loops as possible and then makes it as control dependant as
1540  * possible.
1541  */
1542 static void
1543 place_floats_late(ir_node *n, pdeq *worklist)
1544 {
1545   int i;
1546   ir_node *early;
1547
1548   assert (irn_not_visited(n)); /* no multiple placement */
1549
1550   /* no need to place block nodes, control nodes are already placed. */
1551   if ((get_irn_op(n) != op_Block) &&
1552       (!is_cfop(n)) &&
1553       (get_irn_mode(n) != mode_X)) {
1554     /* Remember the early placement of this block to move it
1555        out of loop no further than the early placement. */
1556     early = get_nodes_block(n);
1557     /* Assure that our users are all placed, except the Phi-nodes.
1558        --- Each data flow cycle contains at least one Phi-node.  We
1559        have to break the `user has to be placed before the
1560        producer' dependence cycle and the Phi-nodes are the
1561        place to do so, because we need to base our placement on the
1562        final region of our users, which is OK with Phi-nodes, as they
1563        are op_pin_state_pinned, and they never have to be placed after a
1564        producer of one of their inputs in the same block anyway. */
1565     for (i = 0; i < get_irn_n_outs(n); i++) {
1566       ir_node *succ = get_irn_out(n, i);
1567       if (irn_not_visited(succ) && (get_irn_op(succ) != op_Phi))
1568     place_floats_late(succ, worklist);
1569     }
1570
1571     /* We have to determine the final block of this node... except for
1572        constants. */
1573     if ((get_op_pinned(get_irn_op(n)) == op_pin_state_floats) &&
1574     (get_irn_op(n) != op_Const) &&
1575     (get_irn_op(n) != op_SymConst)) {
1576       ir_node *dca = NULL;  /* deepest common ancestor in the
1577                    dominator tree of all nodes'
1578                    blocks depending on us; our final
1579                    placement has to dominate DCA. */
1580       for (i = 0; i < get_irn_n_outs(n); i++) {
1581     dca = consumer_dom_dca (dca, get_irn_out(n, i), n);
1582       }
1583       set_nodes_block(n, dca);
1584
1585       move_out_of_loops (n, early);
1586     }
1587   }
1588
1589   mark_irn_visited(n);
1590
1591   /* Add predecessors of all non-floating nodes on list. (Those of floating
1592      nodes are placeded already and therefore are marked.)  */
1593   for (i = 0; i < get_irn_n_outs(n); i++) {
1594     if (irn_not_visited(get_irn_out(n, i))) {
1595       pdeq_putr (worklist, get_irn_out(n, i));
1596     }
1597   }
1598 }
1599
1600 static INLINE void place_late(pdeq* worklist) {
1601   assert(worklist);
1602   inc_irg_visited(current_ir_graph);
1603
1604   /* This fills the worklist initially. */
1605   place_floats_late(get_irg_start_block(current_ir_graph), worklist);
1606   /* And now empty the worklist again... */
1607   while (!pdeq_empty (worklist)) {
1608     ir_node *n = pdeq_getl (worklist);
1609     if (irn_not_visited(n)) place_floats_late(n, worklist);
1610   }
1611 }
1612
1613 void place_code(ir_graph *irg) {
1614   pdeq* worklist;
1615   ir_graph *rem = current_ir_graph;
1616
1617   current_ir_graph = irg;
1618
1619   if (!(get_opt_optimize() && get_opt_global_cse())) return;
1620
1621   /* Handle graph state */
1622   assert(get_irg_phase_state(irg) != phase_building);
1623   if (get_irg_dom_state(irg) != dom_consistent)
1624     compute_doms(irg);
1625
1626   if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) {
1627     free_loop_information(irg);
1628     construct_backedges(irg);
1629   }
1630
1631   /* Place all floating nodes as early as possible. This guarantees
1632      a legal code placement. */
1633   worklist = new_pdeq();
1634   place_early(worklist);
1635
1636   /* place_early invalidates the outs, place_late needs them. */
1637   compute_outs(irg);
1638   /* Now move the nodes down in the dominator tree. This reduces the
1639      unnecessary executions of the node. */
1640   place_late(worklist);
1641
1642   set_irg_outs_inconsistent(current_ir_graph);
1643   set_irg_loopinfo_inconsistent(current_ir_graph);
1644   del_pdeq(worklist);
1645   current_ir_graph = rem;
1646 }
1647
1648
1649
1650 /********************************************************************/
1651 /* Control flow optimization.                                       */
1652 /* Removes Bad control flow predecessors and empty blocks.  A block */
1653 /* is empty if it contains only a Jmp node.                         */
1654 /* Blocks can only be removed if they are not needed for the        */
1655 /* semantics of Phi nodes.                                          */
1656 /********************************************************************/
1657
1658 /**
1659  * Removes Tuples from Block control flow predecessors.
1660  * Optimizes blocks with equivalent_node().
1661  * Replaces n by Bad if n is unreachable control flow.
1662  */
1663 static void merge_blocks(ir_node *n, void *env) {
1664   int i;
1665   set_irn_link(n, NULL);
1666
1667   if (get_irn_op(n) == op_Block) {
1668     /* Remove Tuples */
1669     for (i = 0; i < get_Block_n_cfgpreds(n); i++)
1670       /* GL @@@ : is this possible? if (get_opt_normalize()) -- added, all tests go through.
1671        A different order of optimizations might cause problems. */
1672       if (get_opt_normalize())
1673     set_Block_cfgpred(n, i, skip_Tuple(get_Block_cfgpred(n, i)));
1674   } else if (get_opt_optimize() && (get_irn_mode(n) == mode_X)) {
1675     /* We will soon visit a block.  Optimize it before visiting! */
1676     ir_node *b = get_nodes_block(n);
1677     ir_node *new_node = equivalent_node(b);
1678     while (irn_not_visited(b) && (!is_Bad(new_node)) && (new_node != b)) {
1679       /* We would have to run gigo if new is bad, so we
1680      promote it directly below. */
1681       assert(((b == new_node) ||
1682           get_opt_control_flow_straightening() ||
1683           get_opt_control_flow_weak_simplification()) &&
1684          ("strange flag setting"));
1685       exchange (b, new_node);
1686       b = new_node;
1687       new_node = equivalent_node(b);
1688     }
1689     if (is_Bad(new_node) && get_opt_normalize()) exchange(n, new_Bad());
1690   }
1691 }
1692
1693 /**
1694  * Collects all Phi nodes in link list of Block.
1695  * Marks all blocks "block_visited" if they contain a node other
1696  * than Jmp.
1697  */
1698 static void collect_nodes(ir_node *n, void *env) {
1699   if (is_no_Block(n)) {
1700     ir_node *b = get_nodes_block(n);
1701
1702     if ((get_irn_op(n) == op_Phi)) {
1703       /* Collect Phi nodes to compact ins along with block's ins. */
1704       set_irn_link(n, get_irn_link(b));
1705       set_irn_link(b, n);
1706     } else if ((get_irn_op(n) != op_Jmp) && !is_Bad(b)) {  /* Check for non empty block. */
1707       mark_Block_block_visited(b);
1708     }
1709   }
1710 }
1711
1712 /** Returns true if pred is predecessor of block. */
1713 static int is_pred_of(ir_node *pred, ir_node *b) {
1714   int i;
1715   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1716     ir_node *b_pred = get_nodes_block(get_Block_cfgpred(b, i));
1717     if (b_pred == pred) return 1;
1718   }
1719   return 0;
1720 }
1721
1722 static int test_whether_dispensable(ir_node *b, int pos) {
1723   int i, j, n_preds = 1;
1724   int dispensable = 1;
1725   ir_node *cfop = get_Block_cfgpred(b, pos);
1726   ir_node *pred = get_nodes_block(cfop);
1727
1728   if (get_Block_block_visited(pred) + 1
1729       < get_irg_block_visited(current_ir_graph)) {
1730     if (!get_opt_optimize() || !get_opt_control_flow_strong_simplification()) {
1731       /* Mark block so that is will not be removed. */
1732       set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
1733       return 1;
1734     }
1735     /* Seems to be empty. */
1736     if (!get_irn_link(b)) {
1737       /* There are no Phi nodes ==> dispensable. */
1738       n_preds = get_Block_n_cfgpreds(pred);
1739     } else {
1740       /* b's pred blocks and pred's pred blocks must be pairwise disjunct.
1741      Work preds < pos as if they were already removed. */
1742       for (i = 0; i < pos; i++) {
1743     ir_node *b_pred = get_nodes_block(get_Block_cfgpred(b, i));
1744     if (get_Block_block_visited(b_pred) + 1
1745         < get_irg_block_visited(current_ir_graph)) {
1746       for (j = 0; j < get_Block_n_cfgpreds(b_pred); j++) {
1747         ir_node *b_pred_pred = get_nodes_block(get_Block_cfgpred(b_pred, j));
1748         if (is_pred_of(b_pred_pred, pred)) dispensable = 0;
1749       }
1750     } else {
1751       if (is_pred_of(b_pred, pred)) dispensable = 0;
1752     }
1753       }
1754       for (i = pos +1; i < get_Block_n_cfgpreds(b); i++) {
1755     ir_node *b_pred = get_nodes_block(get_Block_cfgpred(b, i));
1756     if (is_pred_of(b_pred, pred)) dispensable = 0;
1757       }
1758       if (!dispensable) {
1759     set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
1760     n_preds = 1;
1761       } else {
1762         n_preds = get_Block_n_cfgpreds(pred);
1763       }
1764     }
1765   }
1766
1767   return n_preds;
1768 }
1769
1770 static void optimize_blocks(ir_node *b, void *env) {
1771   int i, j, k, max_preds, n_preds;
1772   ir_node *pred, *phi;
1773   ir_node **in;
1774
1775   /* Count the number of predecessor if this block is merged with pred blocks
1776      that are empty. */
1777   max_preds = 0;
1778   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1779     max_preds += test_whether_dispensable(b, i);
1780   }
1781   in = (ir_node **) malloc(max_preds * sizeof(ir_node *));
1782
1783 /*-
1784   printf(" working on "); DDMN(b);
1785   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1786     pred = get_nodes_block(get_Block_cfgpred(b, i));
1787     if (is_Bad(get_Block_cfgpred(b, i))) {
1788       printf("  removing Bad %i\n ", i);
1789     } else if (get_Block_block_visited(pred) +1
1790            < get_irg_block_visited(current_ir_graph)) {
1791       printf("  removing pred %i ", i); DDMN(pred);
1792     } else { printf("  Nothing to do for "); DDMN(pred); }
1793   }
1794   * end Debug output -*/
1795
1796   /*- Fix the Phi nodes -*/
1797   phi = get_irn_link(b);
1798   while (phi) {
1799     assert(get_irn_op(phi) == op_Phi);
1800     /* Find the new predecessors for the Phi */
1801     n_preds = 0;
1802     for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1803       pred = get_nodes_block(get_Block_cfgpred(b, i));
1804       if (is_Bad(get_Block_cfgpred(b, i))) {
1805     /* Do nothing */
1806       } else if (get_Block_block_visited(pred) +1
1807          < get_irg_block_visited(current_ir_graph)) {
1808     /* It's an empty block and not yet visited. */
1809     ir_node *phi_pred = get_Phi_pred(phi, i);
1810     for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
1811       if (get_nodes_block(phi_pred) == pred) {
1812         assert(get_irn_op(phi_pred) == op_Phi);  /* Block is empty!! */
1813         in[n_preds] = get_Phi_pred(phi_pred, j);
1814       } else {
1815         in[n_preds] = phi_pred;
1816       }
1817       n_preds++;
1818     }
1819     /* The Phi_pred node is replaced now if it is a Phi.
1820        In Schleifen kann offenbar der entfernte Phi Knoten legal verwendet werden.
1821        Daher muss der Phiknoten durch den neuen ersetzt werden.
1822        Weiter muss der alte Phiknoten entfernt werden (durch ersetzen oder
1823        durch einen Bad) damit er aus den keep_alive verschwinden kann.
1824        Man sollte also, falls keine Schleife vorliegt, exchange mit new_Bad
1825        aufrufen.  */
1826     if (get_nodes_block(phi_pred) == pred) {
1827       /* remove the Phi as it might be kept alive. Further there
1828          might be other users. */
1829       exchange(phi_pred, phi);  /* geht, ist aber doch semantisch falsch! Warum?? */
1830     }
1831       } else {
1832     in[n_preds] = get_Phi_pred(phi, i);
1833     n_preds ++;
1834       }
1835     }
1836     /* Fix the node */
1837     set_irn_in(phi, n_preds, in);
1838
1839     phi = get_irn_link(phi);
1840   }
1841
1842 /*-
1843       This happens only if merge between loop backedge and single loop entry. -*/
1844   for (k = 0; k < get_Block_n_cfgpreds(b); k++) {
1845     pred = get_nodes_block(get_Block_cfgpred(b, k));
1846     if (get_Block_block_visited(pred)+1 < get_irg_block_visited(current_ir_graph)) {
1847       phi = get_irn_link(pred);
1848       while (phi) {
1849     if (get_irn_op(phi) == op_Phi) {
1850       set_nodes_block(phi, b);
1851
1852       n_preds = 0;
1853       for (i = 0; i < k; i++) {
1854         pred = get_nodes_block(get_Block_cfgpred(b, i));
1855         if (is_Bad(get_Block_cfgpred(b, i))) {
1856           /* Do nothing */
1857         } else if (get_Block_block_visited(pred) +1
1858            < get_irg_block_visited(current_ir_graph)) {
1859           /* It's an empty block and not yet visited. */
1860           for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
1861         /* @@@ Hier brauche ich Schleifeninformation!!! Kontrollflusskante
1862            muss Rueckwaertskante sein! (An allen vier in[n_preds] = phi
1863            Anweisungen.) Trotzdem tuts bisher!! */
1864         in[n_preds] = phi;
1865         n_preds++;
1866           }
1867         } else {
1868           in[n_preds] = phi;
1869           n_preds++;
1870         }
1871       }
1872       for (i = 0; i < get_Phi_n_preds(phi); i++) {
1873         in[n_preds] = get_Phi_pred(phi, i);
1874         n_preds++;
1875       }
1876       for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
1877         pred = get_nodes_block(get_Block_cfgpred(b, i));
1878         if (is_Bad(get_Block_cfgpred(b, i))) {
1879           /* Do nothing */
1880         } else if (get_Block_block_visited(pred) +1
1881            < get_irg_block_visited(current_ir_graph)) {
1882           /* It's an empty block and not yet visited. */
1883           for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
1884         in[n_preds] = phi;
1885         n_preds++;
1886           }
1887         } else {
1888           in[n_preds] = phi;
1889           n_preds++;
1890         }
1891       }
1892       set_irn_in(phi, n_preds, in);
1893     }
1894     phi = get_irn_link(phi);
1895       }
1896     }
1897   }
1898
1899   /*- Fix the block -*/
1900   n_preds = 0;
1901   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1902     pred = get_nodes_block(get_Block_cfgpred(b, i));
1903     if (is_Bad(get_Block_cfgpred(b, i))) {
1904       /* Do nothing */
1905     } else if (get_Block_block_visited(pred) +1
1906            < get_irg_block_visited(current_ir_graph)) {
1907       /* It's an empty block and not yet visited. */
1908       assert(get_Block_n_cfgpreds(b) > 1);
1909                         /* Else it should be optimized by equivalent_node. */
1910       for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
1911     in[n_preds] = get_Block_cfgpred(pred, j);
1912     n_preds++;
1913       }
1914       /* Remove block as it might be kept alive. */
1915       exchange(pred, b/*new_Bad()*/);
1916     } else {
1917       in[n_preds] = get_Block_cfgpred(b, i);
1918       n_preds ++;
1919     }
1920   }
1921   set_irn_in(b, n_preds, in);
1922   free(in);
1923 }
1924
1925 void optimize_cf(ir_graph *irg) {
1926   int i;
1927   ir_node **in;
1928   ir_node *end = get_irg_end(irg);
1929   ir_graph *rem = current_ir_graph;
1930   current_ir_graph = irg;
1931
1932   /* Handle graph state */
1933   assert(get_irg_phase_state(irg) != phase_building);
1934   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
1935     set_irg_outs_inconsistent(current_ir_graph);
1936   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
1937     set_irg_dom_inconsistent(current_ir_graph);
1938
1939   /* Use block visited flag to mark non-empty blocks. */
1940   inc_irg_block_visited(irg);
1941   irg_walk(end, merge_blocks, collect_nodes, NULL);
1942
1943   /* Optimize the standard code. */
1944   irg_block_walk(get_irg_end_block(irg), optimize_blocks, NULL, NULL);
1945
1946   /* Walk all keep alives, optimize them if block, add to new in-array
1947      for end if useful. */
1948   in = NEW_ARR_F (ir_node *, 1);
1949   in[0] = get_nodes_block(end);
1950   inc_irg_visited(current_ir_graph);
1951   for(i = 0; i < get_End_n_keepalives(end); i++) {
1952     ir_node *ka = get_End_keepalive(end, i);
1953     if (irn_not_visited(ka)) {
1954       if ((get_irn_op(ka) == op_Block) && Block_not_block_visited(ka)) {
1955     set_irg_block_visited(current_ir_graph,  /* Don't walk all the way to Start. */
1956               get_irg_block_visited(current_ir_graph)-1);
1957     irg_block_walk(ka, optimize_blocks, NULL, NULL);
1958     mark_irn_visited(ka);
1959     ARR_APP1 (ir_node *, in, ka);
1960       } else if (get_irn_op(ka) == op_Phi) {
1961     mark_irn_visited(ka);
1962     ARR_APP1 (ir_node *, in, ka);
1963       }
1964     }
1965   }
1966   /* DEL_ARR_F(end->in);   GL @@@ tut nicht ! */
1967   end->in = in;
1968
1969   current_ir_graph = rem;
1970 }
1971
1972
1973 /**
1974  * Called by walker of remove_critical_cf_edges().
1975  *
1976  * Place an empty block to an edge between a blocks of multiple
1977  * predecessors and a block of multiple successors.
1978  *
1979  * @param n IR node
1980  * @param env Environment of walker. This field is unused and has
1981  *            the value NULL.
1982  */
1983 static void walk_critical_cf_edges(ir_node *n, void *env) {
1984   int arity, i;
1985   ir_node *pre, *block, **in, *jmp;
1986
1987   /* Block has multiple predecessors */
1988   if ((op_Block == get_irn_op(n)) &&
1989       (get_irn_arity(n) > 1)) {
1990     arity = get_irn_arity(n);
1991
1992     if (n == get_irg_end_block(current_ir_graph))
1993       return;  /*  No use to add a block here.      */
1994
1995     for (i=0; i<arity; i++) {
1996       pre = get_irn_n(n, i);
1997       /* Predecessor has multiple successors. Insert new flow edge */
1998       if ((NULL != pre) &&
1999     (op_Proj == get_irn_op(pre)) &&
2000     op_Raise != get_irn_op(skip_Proj(pre))) {
2001
2002     /* set predecessor array for new block */
2003     in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 1);
2004     /* set predecessor of new block */
2005     in[0] = pre;
2006     block = new_Block(1, in);
2007     /* insert new jmp node to new block */
2008     set_cur_block(block);
2009     jmp = new_Jmp();
2010     set_cur_block(n);
2011     /* set successor of new block */
2012     set_irn_n(n, i, jmp);
2013
2014       } /* predecessor has multiple successors */
2015     } /* for all predecessors */
2016   } /* n is a block */
2017 }
2018
2019 void remove_critical_cf_edges(ir_graph *irg) {
2020   if (get_opt_critical_edges())
2021     irg_walk_graph(irg, NULL, walk_critical_cf_edges, NULL);
2022 }