7f704b48b0b498340cbc7e375d088882ab59b9c9
[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, 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    * currently, we cannot inline two cases:
709    * - call with compound arguments
710    * - graphs that take the address of a parameter
711    */
712   if (! can_inline(call, called_graph))
713     return 0;
714
715   /* --  Turn off optimizations, this can cause problems when allocating new nodes. -- */
716   rem_opt = get_opt_optimize();
717   set_optimize(0);
718
719   /* Handle graph state */
720   assert(get_irg_phase_state(current_ir_graph) != phase_building);
721   assert(get_irg_pinned(current_ir_graph) == pinned);
722   assert(get_irg_pinned(called_graph) == pinned);
723   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
724     set_irg_outs_inconsistent(current_ir_graph);
725   set_irg_loopinfo_inconsistent(current_ir_graph);
726
727   /* -- Check preconditions -- */
728   assert(get_irn_op(call) == op_Call);
729   /* @@@ does not work for InterfaceIII.java after cgana
730      assert(get_Call_type(call) == get_entity_type(get_irg_ent(called_graph)));
731      assert(smaller_type(get_entity_type(get_irg_ent(called_graph)),
732      get_Call_type(call)));
733   */
734   assert(get_type_tpop(get_Call_type(call)) == type_method);
735   if (called_graph == current_ir_graph) {
736     set_optimize(rem_opt);
737     return 0;
738   }
739
740   /* here we know we WILL inline, so inform the statistics */
741   stat_inline(call, called_graph);
742
743   /* -- Decide how to handle exception control flow: Is there a handler
744      for the Call node, or do we branch directly to End on an exception?
745      exc_handling: 0 There is a handler.
746      1 Branches to End.
747      2 Exception handling not represented in Firm. -- */
748   {
749     ir_node *proj, *Mproj = NULL, *Xproj = NULL;
750     for (proj = (ir_node *)get_irn_link(call); proj; proj = (ir_node *)get_irn_link(proj)) {
751       assert(get_irn_op(proj) == op_Proj);
752       if (get_Proj_proj(proj) == pn_Call_X_except) Xproj = proj;
753       if (get_Proj_proj(proj) == pn_Call_M_except) Mproj = proj;
754     }
755     if      (Mproj) { assert(Xproj); exc_handling = 0; } /*  Mproj           */
756     else if (Xproj) {                exc_handling = 1; } /* !Mproj &&  Xproj   */
757     else            {                exc_handling = 2; } /* !Mproj && !Xproj   */
758   }
759
760
761   /* --
762      the procedure and later replaces the Start node of the called graph.
763      Post_call is the old Call node and collects the results of the called
764      graph. Both will end up being a tuple.  -- */
765   post_bl = get_nodes_Block(call);
766   set_irg_current_block(current_ir_graph, post_bl);
767   /* XxMxPxP of Start + parameter of Call */
768   in[pn_Start_X_initial_exec] = new_Jmp();
769   in[pn_Start_M]              = get_Call_mem(call);
770   in[pn_Start_P_frame_base]   = get_irg_frame(current_ir_graph);
771   in[pn_Start_P_globals]      = get_irg_globals(current_ir_graph);
772   in[pn_Start_T_args]         = new_Tuple(get_Call_n_params(call), get_Call_param_arr(call));
773   /* in[pn_Start_P_value_arg_base] = ??? */
774   pre_call = new_Tuple(5, in);
775   post_call = call;
776
777   /* --
778      The new block gets the ins of the old block, pre_call and all its
779      predecessors and all Phi nodes. -- */
780   part_block(pre_call);
781
782   /* -- Prepare state for dead node elimination -- */
783   /* Visited flags in calling irg must be >= flag in called irg.
784      Else walker and arity computation will not work. */
785   if (get_irg_visited(current_ir_graph) <= get_irg_visited(called_graph))
786     set_irg_visited(current_ir_graph, get_irg_visited(called_graph)+1);
787   if (get_irg_block_visited(current_ir_graph)< get_irg_block_visited(called_graph))
788     set_irg_block_visited(current_ir_graph, get_irg_block_visited(called_graph));
789   /* Set pre_call as new Start node in link field of the start node of
790      calling graph and pre_calls block as new block for the start block
791      of calling graph.
792      Further mark these nodes so that they are not visited by the
793      copying. */
794   set_irn_link(get_irg_start(called_graph), pre_call);
795   set_irn_visited(get_irg_start(called_graph), get_irg_visited(current_ir_graph));
796   set_irn_link(get_irg_start_block(called_graph), get_nodes_Block(pre_call));
797   set_irn_visited(get_irg_start_block(called_graph), get_irg_visited(current_ir_graph));
798   set_irn_link(get_irg_bad(called_graph), get_irg_bad(current_ir_graph));
799   set_irn_visited(get_irg_bad(called_graph), get_irg_visited(current_ir_graph));
800
801   /* Initialize for compaction of in arrays */
802   inc_irg_block_visited(current_ir_graph);
803
804   /* -- Replicate local entities of the called_graph -- */
805   /* copy the entities. */
806   called_frame = get_irg_frame_type(called_graph);
807   for (i = 0; i < get_class_n_members(called_frame); i++) {
808     entity *new_ent, *old_ent;
809     old_ent = get_class_member(called_frame, i);
810     new_ent = copy_entity_own(old_ent, get_cur_frame_type());
811     set_entity_link(old_ent, new_ent);
812   }
813
814   /* visited is > than that of called graph.  With this trick visited will
815      remain unchanged so that an outer walker, e.g., searching the call nodes
816      to inline, calling this inline will not visit the inlined nodes. */
817   set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
818
819   /* -- Performing dead node elimination inlines the graph -- */
820   /* Copies the nodes to the obstack of current_ir_graph. Updates links to new
821      entities. */
822   /* @@@ endless loops are not copied!! -- they should be, I think... */
823   irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds,
824            get_irg_frame_type(called_graph));
825
826   /* Repair called_graph */
827   set_irg_visited(called_graph, get_irg_visited(current_ir_graph));
828   set_irg_block_visited(called_graph, get_irg_block_visited(current_ir_graph));
829   set_Block_block_visited(get_irg_start_block(called_graph), 0);
830
831   /* -- Merge the end of the inlined procedure with the call site -- */
832   /* We will turn the old Call node into a Tuple with the following
833      predecessors:
834      -1:  Block of Tuple.
835      0: Phi of all Memories of Return statements.
836      1: Jmp from new Block that merges the control flow from all exception
837      predecessors of the old end block.
838      2: Tuple of all arguments.
839      3: Phi of Exception memories.
840      In case the old Call directly branches to End on an exception we don't
841      need the block merging all exceptions nor the Phi of the exception
842      memories.
843   */
844
845   /* -- Precompute some values -- */
846   end_bl = get_new_node(get_irg_end_block(called_graph));
847   end = get_new_node(get_irg_end(called_graph));
848   arity = get_irn_arity(end_bl);    /* arity = n_exc + n_ret  */
849   n_res = get_method_n_ress(get_Call_type(call));
850
851   res_pred = (ir_node **) malloc (n_res * sizeof (ir_node *));
852   cf_pred =  (ir_node **) malloc (arity * sizeof (ir_node *));
853
854   set_irg_current_block(current_ir_graph, post_bl); /* just to make sure */
855
856   /* -- archive keepalives -- */
857   irn_arity = get_irn_arity(end);
858   for (i = 0; i < irn_arity; i++)
859     add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
860
861   /* The new end node will die.  We need not free as the in array is on the obstack:
862      copy_node only generated 'D' arrays. */
863
864   /* -- Replace Return nodes by Jump nodes. -- */
865   n_ret = 0;
866   for (i = 0; i < arity; i++) {
867     ir_node *ret;
868     ret = get_irn_n(end_bl, i);
869     if (get_irn_op(ret) == op_Return) {
870       cf_pred[n_ret] = new_r_Jmp(current_ir_graph, get_nodes_Block(ret));
871       n_ret++;
872     }
873   }
874   set_irn_in(post_bl, n_ret, cf_pred);
875
876   /* -- Build a Tuple for all results of the method.
877      Add Phi node if there was more than one Return.  -- */
878   turn_into_tuple(post_call, 4);
879   /* First the Memory-Phi */
880   n_ret = 0;
881   for (i = 0; i < arity; i++) {
882     ret = get_irn_n(end_bl, i);
883     if (get_irn_op(ret) == op_Return) {
884       cf_pred[n_ret] = get_Return_mem(ret);
885       n_ret++;
886     }
887   }
888   phi = new_Phi(n_ret, cf_pred, mode_M);
889   set_Tuple_pred(call, pn_Call_M_regular, phi);
890   /* Conserve Phi-list for further inlinings -- but might be optimized */
891   if (get_nodes_Block(phi) == post_bl) {
892     set_irn_link(phi, get_irn_link(post_bl));
893     set_irn_link(post_bl, phi);
894   }
895   /* Now the real results */
896   if (n_res > 0) {
897     for (j = 0; j < n_res; j++) {
898       n_ret = 0;
899       for (i = 0; i < arity; i++) {
900         ret = get_irn_n(end_bl, i);
901         if (get_irn_op(ret) == op_Return) {
902           cf_pred[n_ret] = get_Return_res(ret, j);
903           n_ret++;
904         }
905       }
906       if (n_ret > 0)
907         phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0]));
908       else
909         phi = new_Bad();
910       res_pred[j] = phi;
911       /* Conserve Phi-list for further inlinings -- but might be optimized */
912       if (get_nodes_Block(phi) == post_bl) {
913         set_irn_link(phi, get_irn_link(post_bl));
914         set_irn_link(post_bl, phi);
915       }
916     }
917     set_Tuple_pred(call, pn_Call_T_result, new_Tuple(n_res, res_pred));
918   } else {
919     set_Tuple_pred(call, pn_Call_T_result, new_Bad());
920   }
921   /* Finally the exception control flow.
922      We have two (three) possible situations:
923      First if the Call branches to an exception handler: We need to add a Phi node to
924      collect the memory containing the exception objects.  Further we need
925      to add another block to get a correct representation of this Phi.  To
926      this block we add a Jmp that resolves into the X output of the Call
927      when the Call is turned into a tuple.
928      Second the Call branches to End, the exception is not handled.  Just
929      add all inlined exception branches to the End node.
930      Third: there is no Exception edge at all. Handle as case two. */
931   if (exc_handling == 0) {
932     n_exc = 0;
933     for (i = 0; i < arity; i++) {
934       ir_node *ret;
935       ret = get_irn_n(end_bl, i);
936       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
937         cf_pred[n_exc] = ret;
938         n_exc++;
939       }
940     }
941     if (n_exc > 0) {
942       new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
943       set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
944       /* The Phi for the memories with the exception objects */
945       n_exc = 0;
946       for (i = 0; i < arity; i++) {
947         ir_node *ret;
948         ret = skip_Proj(get_irn_n(end_bl, i));
949         if (get_irn_op(ret) == op_Call) {
950           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 3);
951           n_exc++;
952         } else if (is_fragile_op(ret)) {
953           /* We rely that all cfops have the memory output at the same position. */
954           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 0);
955           n_exc++;
956         } else if (get_irn_op(ret) == op_Raise) {
957           cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_Block(ret), ret, mode_M, 1);
958           n_exc++;
959         }
960       }
961       set_Tuple_pred(call, pn_Call_M_except, new_Phi(n_exc, cf_pred, mode_M));
962     } else {
963       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
964       set_Tuple_pred(call, pn_Call_M_except, new_Bad());
965     }
966   } else {
967     ir_node *main_end_bl;
968     int main_end_bl_arity;
969     ir_node **end_preds;
970
971     /* assert(exc_handling == 1 || no exceptions. ) */
972     n_exc = 0;
973     for (i = 0; i < arity; i++) {
974       ir_node *ret = get_irn_n(end_bl, i);
975
976       if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
977         cf_pred[n_exc] = ret;
978         n_exc++;
979       }
980     }
981     main_end_bl = get_irg_end_block(current_ir_graph);
982     main_end_bl_arity = get_irn_arity(main_end_bl);
983     end_preds =  (ir_node **) malloc ((n_exc + main_end_bl_arity) * sizeof (ir_node *));
984
985     for (i = 0; i < main_end_bl_arity; ++i)
986       end_preds[i] = get_irn_n(main_end_bl, i);
987     for (i = 0; i < n_exc; ++i)
988       end_preds[main_end_bl_arity + i] = cf_pred[i];
989     set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
990     set_Tuple_pred(call, pn_Call_X_except, new_Bad());
991     set_Tuple_pred(call, pn_Call_M_except, new_Bad());
992     free(end_preds);
993   }
994   free(res_pred);
995   free(cf_pred);
996
997 #if 0  /* old. now better, correcter, faster implementation. */
998   if (n_exc > 0) {
999     /* -- If the exception control flow from the inlined Call directly
1000        branched to the end block we now have the following control
1001        flow predecessor pattern: ProjX -> Tuple -> Jmp.  We must
1002        remove the Jmp along with it's empty block and add Jmp's
1003        predecessors as predecessors of this end block.  No problem if
1004        there is no exception, because then branches Bad to End which
1005        is fine. --
1006        @@@ can't we know this beforehand: by getting the Proj(1) from
1007        the Call link list and checking whether it goes to Proj. */
1008     /* find the problematic predecessor of the end block. */
1009     end_bl = get_irg_end_block(current_ir_graph);
1010     for (i = 0; i < get_Block_n_cfgpreds(end_bl); i++) {
1011       cf_op = get_Block_cfgpred(end_bl, i);
1012       if (get_irn_op(cf_op) == op_Proj) {
1013         cf_op = get_Proj_pred(cf_op);
1014         if ((get_irn_op(cf_op) == op_Tuple) && (cf_op == call)) {
1015           /*  There are unoptimized tuples from inlineing before when no exc */
1016           assert(get_Proj_proj(get_Block_cfgpred(end_bl, i)) == pn_Call_X_except);
1017           cf_op = get_Tuple_pred(cf_op, pn_Call_X_except);
1018           assert(get_irn_op(cf_op) == op_Jmp);
1019           break;
1020         }
1021       }
1022     }
1023     /* repair */
1024     if (i < get_Block_n_cfgpreds(end_bl)) {
1025       bl = get_nodes_Block(cf_op);
1026       arity = get_Block_n_cfgpreds(end_bl) + get_Block_n_cfgpreds(bl) - 1;
1027       cf_pred = (ir_node **) malloc (arity * sizeof (ir_node *));
1028       for (j = 0; j < i; j++)
1029         cf_pred[j] = get_Block_cfgpred(end_bl, j);
1030       for (j = j; j < i + get_Block_n_cfgpreds(bl); j++)
1031         cf_pred[j] = get_Block_cfgpred(bl, j-i);
1032       for (j = j; j < arity; j++)
1033         cf_pred[j] = get_Block_cfgpred(end_bl, j-get_Block_n_cfgpreds(bl) +1);
1034       set_irn_in(end_bl, arity, cf_pred);
1035       free(cf_pred);
1036       /*  Remove the exception pred from post-call Tuple. */
1037       set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1038     }
1039   }
1040 #endif
1041
1042   /* --  Turn cse back on. -- */
1043   set_optimize(rem_opt);
1044
1045   return 1;
1046 }
1047
1048 /********************************************************************/
1049 /* Apply inlineing to small methods.                                */
1050 /********************************************************************/
1051
1052 /* It makes no sense to inline too many calls in one procedure. Anyways,
1053    I didn't get a version with NEW_ARR_F to run. */
1054 #define MAX_INLINE 1024
1055
1056 /**
1057  * environment for inlining small irgs
1058  */
1059 typedef struct _inline_env_t {
1060   int pos;
1061   ir_node *calls[MAX_INLINE];
1062 } inline_env_t;
1063
1064 /**
1065  * Returns the irg called from a Call node. If the irg is not
1066  * known, NULL is returned.
1067  */
1068 static ir_graph *get_call_called_irg(ir_node *call) {
1069   ir_node *addr;
1070   tarval *tv;
1071   ir_graph *called_irg = NULL;
1072
1073   assert(get_irn_op(call) == op_Call);
1074
1075   addr = get_Call_ptr(call);
1076   if (get_irn_op(addr) == op_Const) {
1077     /* Check whether the constant is the pointer to a compiled entity. */
1078     tv = get_Const_tarval(addr);
1079     if (get_tarval_entity(tv))
1080       called_irg = get_entity_irg(get_tarval_entity(tv));
1081   } else if (get_irn_op(addr) == op_SymConst && get_SymConst_kind(addr) == symconst_addr_ent) {
1082     called_irg = get_entity_irg(get_SymConst_entity(addr));
1083   }
1084   return called_irg;
1085 }
1086
1087 static void collect_calls(ir_node *call, void *env) {
1088   inline_env_t *ienv = env;
1089   ir_node *addr;
1090   tarval *tv;
1091   ir_graph *called_irg;
1092
1093   if (get_irn_op(call) != op_Call) return;
1094
1095   addr = get_Call_ptr(call);
1096   if (get_irn_op(addr) == op_Const) {
1097     /* Check whether the constant is the pointer to a compiled entity. */
1098     tv = get_Const_tarval(addr);
1099     if (get_tarval_entity(tv)) {
1100       called_irg = get_entity_irg(get_tarval_entity(tv));
1101       if (called_irg && ienv->pos < MAX_INLINE) {
1102         /* The Call node calls a locally defined method.  Remember to inline. */
1103         ienv->calls[ienv->pos++] = call;
1104       }
1105     }
1106   }
1107 }
1108
1109 /**
1110  * Inlines all small methods at call sites where the called address comes
1111  * from a Const node that references the entity representing the called
1112  * method.
1113  * The size argument is a rough measure for the code size of the method:
1114  * Methods where the obstack containing the firm graph is smaller than
1115  * size are inlined.
1116  */
1117 void inline_small_irgs(ir_graph *irg, int size) {
1118   int i;
1119   ir_graph *rem = current_ir_graph;
1120   inline_env_t env;
1121
1122   if (!(get_opt_optimize() && get_opt_inline())) return;
1123
1124   current_ir_graph = irg;
1125   /* Handle graph state */
1126   assert(get_irg_phase_state(current_ir_graph) != phase_building);
1127   free_callee_info(current_ir_graph);
1128
1129   /* Find Call nodes to inline.
1130      (We can not inline during a walk of the graph, as inlineing the same
1131      method several times changes the visited flag of the walked graph:
1132      after the first inlineing visited of the callee equals visited of
1133      the caller.  With the next inlineing both are increased.) */
1134   env.pos = 0;
1135   irg_walk(get_irg_end(irg), NULL, collect_calls, &env);
1136
1137   if ((env.pos > 0) && (env.pos < MAX_INLINE)) {
1138     /* There are calls to inline */
1139     collect_phiprojs(irg);
1140     for (i = 0; i < env.pos; i++) {
1141       tarval *tv;
1142       ir_graph *callee;
1143       tv = get_Const_tarval(get_Call_ptr(env.calls[i]));
1144       callee = get_entity_irg(get_tarval_entity(tv));
1145       if (((_obstack_memory_used(callee->obst) - obstack_room(callee->obst)) < size) ||
1146         (get_irg_inline_property(callee) == irg_inline_forced)) {
1147         inline_method(env.calls[i], callee);
1148       }
1149     }
1150   }
1151
1152   current_ir_graph = rem;
1153 }
1154
1155 /**
1156  * Environment for inlining irgs.
1157  */
1158 typedef struct {
1159   int n_nodes;       /**< Nodes in graph except Id, Tuple, Proj, Start, End */
1160   int n_nodes_orig;  /**< for statistics */
1161   eset *call_nodes;  /**< All call nodes in this graph */
1162   int n_call_nodes;
1163   int n_call_nodes_orig; /**< for statistics */
1164   int n_callers;   /**< Number of known graphs that call this graphs. */
1165   int n_callers_orig; /**< for statistics */
1166 } inline_irg_env;
1167
1168 static inline_irg_env *new_inline_irg_env(void) {
1169   inline_irg_env *env = malloc(sizeof(inline_irg_env));
1170   env->n_nodes = -2; /* uncount Start, End */
1171   env->n_nodes_orig = -2; /* uncount Start, End */
1172   env->call_nodes = eset_create();
1173   env->n_call_nodes = 0;
1174   env->n_call_nodes_orig = 0;
1175   env->n_callers = 0;
1176   env->n_callers_orig = 0;
1177   return env;
1178 }
1179
1180 static void free_inline_irg_env(inline_irg_env *env) {
1181   eset_destroy(env->call_nodes);
1182   free(env);
1183 }
1184
1185 static void collect_calls2(ir_node *call, void *env) {
1186   inline_irg_env *x = (inline_irg_env *)env;
1187   ir_op *op = get_irn_op(call);
1188   ir_graph *callee;
1189
1190   /* count nodes in irg */
1191   if (op != op_Proj && op != op_Tuple && op != op_Sync) {
1192     x->n_nodes++;
1193     x->n_nodes_orig++;
1194   }
1195
1196   if (op != op_Call) return;
1197
1198   /* collect all call nodes */
1199   eset_insert(x->call_nodes, (void *)call);
1200   x->n_call_nodes++;
1201   x->n_call_nodes_orig++;
1202
1203   /* count all static callers */
1204   callee = get_call_called_irg(call);
1205   if (callee) {
1206     ((inline_irg_env *)get_irg_link(callee))->n_callers++;
1207     ((inline_irg_env *)get_irg_link(callee))->n_callers_orig++;
1208   }
1209 }
1210
1211 INLINE static int is_leave(ir_graph *irg) {
1212   return (((inline_irg_env *)get_irg_link(irg))->n_call_nodes == 0);
1213 }
1214
1215 INLINE static int is_smaller(ir_graph *callee, int size) {
1216   return (((inline_irg_env *)get_irg_link(callee))->n_nodes < size);
1217 }
1218
1219
1220 /*
1221  * Inlines small leave methods at call sites where the called address comes
1222  * from a Const node that references the entity representing the called
1223  * method.
1224  * The size argument is a rough measure for the code size of the method:
1225  * Methods where the obstack containing the firm graph is smaller than
1226  * size are inlined.
1227  */
1228 void inline_leave_functions(int maxsize, int leavesize, int size) {
1229   inline_irg_env *env;
1230   int i, n_irgs = get_irp_n_irgs();
1231   ir_graph *rem = current_ir_graph;
1232   int did_inline = 1;
1233
1234   if (!(get_opt_optimize() && get_opt_inline())) return;
1235
1236   /* extend all irgs by a temporary data structure for inlineing. */
1237   for (i = 0; i < n_irgs; ++i)
1238     set_irg_link(get_irp_irg(i), new_inline_irg_env());
1239
1240   /* Precompute information in temporary data structure. */
1241   for (i = 0; i < n_irgs; ++i) {
1242     current_ir_graph = get_irp_irg(i);
1243     assert(get_irg_phase_state(current_ir_graph) != phase_building);
1244     free_callee_info(current_ir_graph);
1245
1246     irg_walk(get_irg_end(current_ir_graph), NULL, collect_calls2,
1247          get_irg_link(current_ir_graph));
1248   }
1249
1250   /* and now inline.
1251      Inline leaves recursively -- we might construct new leaves. */
1252   /* int itercnt = 1; */
1253   while (did_inline) {
1254     /* printf("iteration %d\n", itercnt++); */
1255     did_inline = 0;
1256     for (i = 0; i < n_irgs; ++i) {
1257       ir_node *call;
1258       eset *walkset;
1259       int phiproj_computed = 0;
1260
1261       current_ir_graph = get_irp_irg(i);
1262       env = (inline_irg_env *)get_irg_link(current_ir_graph);
1263
1264       /* we can not walk and change a set, nor remove from it.
1265       So recompute.*/
1266       walkset = env->call_nodes;
1267       env->call_nodes = eset_create();
1268       for (call = eset_first(walkset); call; call = eset_next(walkset)) {
1269         inline_irg_env *callee_env;
1270         ir_graph *callee = get_call_called_irg(call);
1271
1272         if (env->n_nodes > maxsize) break;
1273         if (callee &&
1274         ((is_leave(callee) && is_smaller(callee, leavesize)) ||
1275          (get_irg_inline_property(callee) == irg_inline_forced))) {
1276           if (!phiproj_computed) {
1277             phiproj_computed = 1;
1278             collect_phiprojs(current_ir_graph);
1279           }
1280           callee_env = (inline_irg_env *)get_irg_link(callee);
1281 /*         printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)), */
1282 /*         get_entity_name(get_irg_entity(callee))); */
1283           if (inline_method(call, callee)) {
1284             did_inline = 1;
1285             env->n_call_nodes--;
1286             eset_insert_all(env->call_nodes, callee_env->call_nodes);
1287             env->n_call_nodes += callee_env->n_call_nodes;
1288             env->n_nodes += callee_env->n_nodes;
1289             callee_env->n_callers--;
1290           }
1291         } else {
1292           eset_insert(env->call_nodes, call);
1293         }
1294       }
1295       eset_destroy(walkset);
1296     }
1297   }
1298
1299   /* printf("Non leaves\n"); */
1300   /* inline other small functions. */
1301   for (i = 0; i < n_irgs; ++i) {
1302     ir_node *call;
1303     eset *walkset;
1304     int phiproj_computed = 0;
1305
1306     current_ir_graph = get_irp_irg(i);
1307     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1308
1309     /* we can not walk and change a set, nor remove from it.
1310        So recompute.*/
1311     walkset = env->call_nodes;
1312     env->call_nodes = eset_create();
1313     for (call = eset_first(walkset); call; call = eset_next(walkset)) {
1314       inline_irg_env *callee_env;
1315       ir_graph *callee = get_call_called_irg(call);
1316
1317       if (env->n_nodes > maxsize) break;
1318       if (callee && is_smaller(callee, size)) {
1319         if (!phiproj_computed) {
1320             phiproj_computed = 1;
1321             collect_phiprojs(current_ir_graph);
1322         }
1323         callee_env = (inline_irg_env *)get_irg_link(callee);
1324 /*       printf(" %s: Inlineing %s.\n", get_entity_name(get_irg_entity(current_ir_graph)), */
1325 /*       get_entity_name(get_irg_entity(callee))); */
1326         if (inline_method(call, callee)) {
1327       did_inline = 1;
1328       env->n_call_nodes--;
1329       eset_insert_all(env->call_nodes, callee_env->call_nodes);
1330       env->n_call_nodes += callee_env->n_call_nodes;
1331       env->n_nodes += callee_env->n_nodes;
1332       callee_env->n_callers--;
1333     }
1334       } else {
1335         eset_insert(env->call_nodes, call);
1336       }
1337     }
1338     eset_destroy(walkset);
1339   }
1340
1341   for (i = 0; i < n_irgs; ++i) {
1342     current_ir_graph = get_irp_irg(i);
1343 #if 0
1344     env = (inline_irg_env *)get_irg_link(current_ir_graph);
1345     if ((env->n_call_nodes_orig != env->n_call_nodes) ||
1346     (env->n_callers_orig != env->n_callers))
1347       printf("Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
1348          env->n_nodes_orig, env->n_nodes, env->n_call_nodes_orig, env->n_call_nodes,
1349          env->n_callers_orig, env->n_callers,
1350          get_entity_name(get_irg_entity(current_ir_graph)));
1351 #endif
1352     free_inline_irg_env((inline_irg_env *)get_irg_link(current_ir_graph));
1353   }
1354
1355   current_ir_graph = rem;
1356 }
1357
1358 /*******************************************************************/
1359 /*  Code Placement.  Pins all floating nodes to a block where they */
1360 /*  will be executed only if needed.                               */
1361 /*******************************************************************/
1362
1363 /**
1364  * Find the earliest correct block for N.  --- Place N into the
1365  * same Block as its dominance-deepest Input.
1366  */
1367 static void
1368 place_floats_early(ir_node *n, pdeq *worklist)
1369 {
1370   int i, start, irn_arity;
1371
1372   /* we must not run into an infinite loop */
1373   assert (irn_not_visited(n));
1374   mark_irn_visited(n);
1375
1376   /* Place floating nodes. */
1377   if (get_op_pinned(get_irn_op(n)) == floats) {
1378     int depth         = 0;
1379     ir_node *b        = new_Bad();   /* The block to place this node in */
1380     int bad_recursion = is_Bad(get_nodes_block(n));
1381
1382     assert(get_irn_op(n) != op_Block);
1383
1384     if ((get_irn_op(n) == op_Const) ||
1385         (get_irn_op(n) == op_SymConst) ||
1386         (is_Bad(n)) ||
1387         (get_irn_op(n) == op_Unknown)) {
1388       /* These nodes will not be placed by the loop below. */
1389       b = get_irg_start_block(current_ir_graph);
1390       depth = 1;
1391     }
1392
1393     /* find the block for this node. */
1394     irn_arity = get_irn_arity(n);
1395     for (i = 0; i < irn_arity; i++) {
1396       ir_node *dep = get_irn_n(n, i);
1397       ir_node *dep_block;
1398
1399       if ((irn_not_visited(dep))
1400           && (get_op_pinned(get_irn_op(dep)) == floats)) {
1401         place_floats_early(dep, worklist);
1402       }
1403
1404       /*
1405        * A node in the Bad block must stay in the bad block,
1406        * so don't compute a new block for it.
1407        */
1408       if (bad_recursion)
1409         continue;
1410
1411       /* Because all loops contain at least one pinned node, now all
1412          our inputs are either pinned or place_early has already
1413          been finished on them.  We do not have any unfinished inputs!  */
1414       dep_block = get_nodes_Block(dep);
1415       if ((!is_Bad(dep_block)) &&
1416           (get_Block_dom_depth(dep_block) > depth)) {
1417         b = dep_block;
1418         depth = get_Block_dom_depth(dep_block);
1419       }
1420       /* Avoid that the node is placed in the Start block */
1421       if ((depth == 1) && (get_Block_dom_depth(get_nodes_Block(n)) > 1)) {
1422         b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
1423         assert(b != get_irg_start_block(current_ir_graph));
1424         depth = 2;
1425       }
1426     }
1427     set_nodes_Block(n, b);
1428   }
1429
1430   /* Add predecessors of non floating nodes on worklist. */
1431   start = (get_irn_op(n) == op_Block) ? 0 : -1;
1432   irn_arity = get_irn_arity(n);
1433   for (i = start; i < irn_arity; i++) {
1434     ir_node *pred = get_irn_n(n, i);
1435     if (irn_not_visited(pred)) {
1436       pdeq_putr (worklist, pred);
1437     }
1438   }
1439 }
1440
1441 /**
1442  * Floating nodes form subgraphs that begin at nodes as Const, Load,
1443  * Start, Call and that end at pinned nodes as Store, Call.  Place_early
1444  * places all floating nodes reachable from its argument through floating
1445  * nodes and adds all beginnings at pinned nodes to the worklist.
1446  */
1447 static INLINE void place_early(pdeq* worklist) {
1448   assert(worklist);
1449   inc_irg_visited(current_ir_graph);
1450
1451   /* this inits the worklist */
1452   place_floats_early(get_irg_end(current_ir_graph), worklist);
1453
1454   /* Work the content of the worklist. */
1455   while (!pdeq_empty (worklist)) {
1456     ir_node *n = pdeq_getl (worklist);
1457     if (irn_not_visited(n)) place_floats_early(n, worklist);
1458   }
1459
1460   set_irg_outs_inconsistent(current_ir_graph);
1461   current_ir_graph->pinned = pinned;
1462 }
1463
1464
1465 /** deepest common dominance ancestor of DCA and CONSUMER of PRODUCER. */
1466 static ir_node *
1467 consumer_dom_dca (ir_node *dca, ir_node *consumer, ir_node *producer)
1468 {
1469   ir_node *block = NULL;
1470
1471   /* Compute the latest block into which we can place a node so that it is
1472      before consumer. */
1473   if (get_irn_op(consumer) == op_Phi) {
1474     /* our consumer is a Phi-node, the effective use is in all those
1475        blocks through which the Phi-node reaches producer */
1476     int i, irn_arity;
1477     ir_node *phi_block = get_nodes_Block(consumer);
1478     irn_arity = get_irn_arity(consumer);
1479     for (i = 0;  i < irn_arity; i++) {
1480       if (get_irn_n(consumer, i) == producer) {
1481         block = get_nodes_Block(get_Block_cfgpred(phi_block, i));
1482       }
1483     }
1484   } else {
1485     assert(is_no_Block(consumer));
1486     block = get_nodes_Block(consumer);
1487   }
1488
1489   /* Compute the deepest common ancestor of block and dca. */
1490   assert(block);
1491   if (!dca) return block;
1492   while (get_Block_dom_depth(block) > get_Block_dom_depth(dca))
1493     block = get_Block_idom(block);
1494   while (get_Block_dom_depth(dca) > get_Block_dom_depth(block))
1495     dca = get_Block_idom(dca);
1496   while (block != dca)
1497     { block = get_Block_idom(block); dca = get_Block_idom(dca); }
1498
1499   return dca;
1500 }
1501
1502 static INLINE int get_irn_loop_depth(ir_node *n) {
1503   return get_loop_depth(get_irn_loop(n));
1504 }
1505
1506 /**
1507  * Move n to a block with less loop depth than it's current block. The
1508  * new block must be dominated by early.
1509  */
1510 static void
1511 move_out_of_loops (ir_node *n, ir_node *early)
1512 {
1513   ir_node *best, *dca;
1514   assert(n && early);
1515
1516
1517   /* Find the region deepest in the dominator tree dominating
1518      dca with the least loop nesting depth, but still dominated
1519      by our early placement. */
1520   dca = get_nodes_Block(n);
1521   best = dca;
1522   while (dca != early) {
1523     dca = get_Block_idom(dca);
1524     if (!dca) break; /* should we put assert(dca)? */
1525     if (get_irn_loop_depth(dca) < get_irn_loop_depth(best)) {
1526       best = dca;
1527     }
1528   }
1529   if (best != get_nodes_Block(n)) {
1530     /* debug output
1531     printf("Moving out of loop: "); DDMN(n);
1532     printf(" Outermost block: "); DDMN(early);
1533     printf(" Best block: "); DDMN(best);
1534     printf(" Innermost block: "); DDMN(get_nodes_Block(n));
1535     */
1536     set_nodes_Block(n, best);
1537   }
1538 }
1539
1540 /**
1541  * Find the latest legal block for N and place N into the
1542  * `optimal' Block between the latest and earliest legal block.
1543  * The `optimal' block is the dominance-deepest block of those
1544  * with the least loop-nesting-depth.  This places N out of as many
1545  * loops as possible and then makes it as control dependant as
1546  * possible.
1547  */
1548 static void
1549 place_floats_late(ir_node *n, pdeq *worklist)
1550 {
1551   int i;
1552   ir_node *early;
1553
1554   assert (irn_not_visited(n)); /* no multiple placement */
1555
1556   /* no need to place block nodes, control nodes are already placed. */
1557   if ((get_irn_op(n) != op_Block) &&
1558       (!is_cfop(n)) &&
1559       (get_irn_mode(n) != mode_X)) {
1560     /* Remember the early placement of this block to move it
1561        out of loop no further than the early placement. */
1562     early = get_nodes_Block(n);
1563     /* Assure that our users are all placed, except the Phi-nodes.
1564        --- Each data flow cycle contains at least one Phi-node.  We
1565        have to break the `user has to be placed before the
1566        producer' dependence cycle and the Phi-nodes are the
1567        place to do so, because we need to base our placement on the
1568        final region of our users, which is OK with Phi-nodes, as they
1569        are pinned, and they never have to be placed after a
1570        producer of one of their inputs in the same block anyway. */
1571     for (i = 0; i < get_irn_n_outs(n); i++) {
1572       ir_node *succ = get_irn_out(n, i);
1573       if (irn_not_visited(succ) && (get_irn_op(succ) != op_Phi))
1574         place_floats_late(succ, worklist);
1575     }
1576
1577     /* We have to determine the final block of this node... except for
1578        constants. */
1579     if ((get_op_pinned(get_irn_op(n)) == floats) &&
1580         (get_irn_op(n) != op_Const) &&
1581         (get_irn_op(n) != op_SymConst)) {
1582       ir_node *dca = NULL;  /* deepest common ancestor in the
1583                    dominator tree of all nodes'
1584                    blocks depending on us; our final
1585                    placement has to dominate DCA. */
1586       for (i = 0; i < get_irn_n_outs(n); i++) {
1587         dca = consumer_dom_dca (dca, get_irn_out(n, i), n);
1588       }
1589       set_nodes_Block(n, dca);
1590
1591       move_out_of_loops (n, early);
1592     }
1593   }
1594
1595   mark_irn_visited(n);
1596
1597   /* Add predecessors of all non-floating nodes on list. (Those of floating
1598      nodes are placeded already and therefore are marked.)  */
1599   for (i = 0; i < get_irn_n_outs(n); i++) {
1600     if (irn_not_visited(get_irn_out(n, i))) {
1601       pdeq_putr (worklist, get_irn_out(n, i));
1602     }
1603   }
1604 }
1605
1606 static INLINE void place_late(pdeq *worklist) {
1607   assert(worklist);
1608   inc_irg_visited(current_ir_graph);
1609
1610   /* This fills the worklist initially. */
1611   place_floats_late(get_irg_start_block(current_ir_graph), worklist);
1612   /* And now empty the worklist again... */
1613   while (!pdeq_empty (worklist)) {
1614     ir_node *n = pdeq_getl (worklist);
1615     if (irn_not_visited(n)) place_floats_late(n, worklist);
1616   }
1617 }
1618
1619 void place_code(ir_graph *irg) {
1620   pdeq* worklist;
1621   ir_graph *rem = current_ir_graph;
1622
1623   current_ir_graph = irg;
1624
1625   if (!(get_opt_optimize() && get_opt_global_cse())) return;
1626
1627   /* Handle graph state */
1628   assert(get_irg_phase_state(irg) != phase_building);
1629   if (get_irg_dom_state(irg) != dom_consistent)
1630     compute_doms(irg);
1631
1632   if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) {
1633     free_loop_information(irg);
1634     construct_backedges(irg);
1635   }
1636
1637   /* Place all floating nodes as early as possible. This guarantees
1638      a legal code placement. */
1639   worklist = new_pdeq();
1640   place_early(worklist);
1641
1642   /* place_early invalidates the outs, place_late needs them. */
1643   compute_outs(irg);
1644   /* Now move the nodes down in the dominator tree. This reduces the
1645      unnecessary executions of the node. */
1646   place_late(worklist);
1647
1648   set_irg_outs_inconsistent(current_ir_graph);
1649   set_irg_loopinfo_inconsistent(current_ir_graph);
1650   del_pdeq(worklist);
1651   current_ir_graph = rem;
1652 }
1653
1654
1655
1656 /********************************************************************/
1657 /* Control flow optimization.                                       */
1658 /* Removes Bad control flow predecessors and empty blocks.  A block */
1659 /* is empty if it contains only a Jmp node.                         */
1660 /* Blocks can only be removed if they are not needed for the        */
1661 /* semantics of Phi nodes.                                          */
1662 /********************************************************************/
1663
1664 /**
1665  * Removes Tuples from Block control flow predecessors.
1666  * Optimizes blocks with equivalent_node().
1667  * Replaces n by Bad if n is unreachable control flow.
1668  */
1669 static void merge_blocks(ir_node *n, void *env) {
1670   int i;
1671   set_irn_link(n, NULL);
1672
1673   if (get_irn_op(n) == op_Block) {
1674     /* Remove Tuples */
1675     for (i = 0; i < get_Block_n_cfgpreds(n); i++)
1676       /* GL @@@ : is this possible? if (get_opt_normalize()) -- added, all tests go through.
1677        A different order of optimizations might cause problems. */
1678       if (get_opt_normalize())
1679         set_Block_cfgpred(n, i, skip_Tuple(get_Block_cfgpred(n, i)));
1680   } else if (get_opt_optimize() && (get_irn_mode(n) == mode_X)) {
1681     /* We will soon visit a block.  Optimize it before visiting! */
1682     ir_node *b = get_nodes_Block(n);
1683     ir_node *new_node = equivalent_node(b);
1684     while (irn_not_visited(b) && (!is_Bad(new_node)) && (new_node != b)) {
1685       /* We would have to run gigo if new is bad, so we
1686          promote it directly below. */
1687       assert(((b == new_node) ||
1688           get_opt_control_flow_straightening() ||
1689           get_opt_control_flow_weak_simplification()) &&
1690          ("strange flag setting"));
1691       exchange (b, new_node);
1692       b = new_node;
1693       new_node = equivalent_node(b);
1694     }
1695     if (is_Bad(new_node) && get_opt_normalize()) exchange(n, new_Bad());
1696   }
1697 }
1698
1699 /**
1700  * Collects all Phi nodes in link list of Block.
1701  * Marks all blocks "block_visited" if they contain a node other
1702  * than Jmp.
1703  *
1704  * Colelct Conds and its Projs in the cond_list
1705  */
1706 static void collect_nodes(ir_node *n, void *env) {
1707   ir_node **cond_list = env;
1708
1709   if (is_no_Block(n)) {
1710     ir_node *b = get_nodes_Block(n);
1711
1712     switch (get_irn_opcode(n)) {
1713
1714     case iro_Phi:
1715       /* Collect Phi nodes to compact ins along with block's ins. */
1716       set_irn_link(n, get_irn_link(b));
1717       set_irn_link(b, n);
1718       break;
1719
1720     case iro_Cond:
1721       {
1722         ir_node *value = get_Cond_selector(n);
1723         tarval *tv = computed_value(value);
1724
1725         if (tv != tarval_bad && mode_is_int(get_tarval_mode(tv))) {
1726           set_irn_link(n, *cond_list);
1727           *cond_list = n;
1728         }
1729         else { /* mark the cond, we cannot optimize it */
1730           set_irn_link(n, NULL);
1731         }
1732       }
1733       break;
1734
1735     case iro_Proj:
1736       {
1737         ir_node *cond = get_Proj_pred(n);
1738
1739         if (get_irn_op(cond) == op_Cond) {
1740           void *link = get_irn_link(cond);
1741
1742           if (link) {
1743             /* the cond node can be optimized, collect Proj */
1744             set_irn_link(n, link);
1745             set_irn_link(cond, n);
1746           }
1747         }
1748       }
1749       break;
1750
1751     default:
1752       break;
1753     }
1754
1755     if ((get_irn_op(n) != op_Jmp) && !is_Bad(b)) {  /* Check for non empty block. */
1756       mark_Block_block_visited(b);
1757     }
1758   }
1759 }
1760
1761 /** Returns true if pred is predecessor of block. */
1762 static int is_pred_of(ir_node *pred, ir_node *b) {
1763   int i;
1764   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1765     ir_node *b_pred = get_nodes_Block(get_Block_cfgpred(b, i));
1766     if (b_pred == pred) return 1;
1767   }
1768   return 0;
1769 }
1770
1771 static int test_whether_dispensable(ir_node *b, int pos) {
1772   int i, j, n_preds = 1;
1773   int dispensable = 1;
1774   ir_node *cfop = get_Block_cfgpred(b, pos);
1775   ir_node *pred = get_nodes_Block(cfop);
1776
1777   if (get_Block_block_visited(pred) + 1
1778       < get_irg_block_visited(current_ir_graph)) {
1779     if (!get_opt_optimize() || !get_opt_control_flow_strong_simplification()) {
1780       /* Mark block so that is will not be removed. */
1781       set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
1782       return 1;
1783     }
1784     /* Seems to be empty. */
1785     if (!get_irn_link(b)) {
1786       /* There are no Phi nodes ==> dispensable. */
1787       n_preds = get_Block_n_cfgpreds(pred);
1788     } else {
1789       /* b's pred blocks and pred's pred blocks must be pairwise disjunct.
1790          Work preds < pos as if they were already removed. */
1791       for (i = 0; i < pos; i++) {
1792         ir_node *b_pred = get_nodes_Block(get_Block_cfgpred(b, i));
1793         if (get_Block_block_visited(b_pred) + 1
1794             < get_irg_block_visited(current_ir_graph)) {
1795           for (j = 0; j < get_Block_n_cfgpreds(b_pred); j++) {
1796             ir_node *b_pred_pred = get_nodes_Block(get_Block_cfgpred(b_pred, j));
1797             if (is_pred_of(b_pred_pred, pred)) dispensable = 0;
1798           }
1799         } else {
1800           if (is_pred_of(b_pred, pred)) dispensable = 0;
1801         }
1802       }
1803       for (i = pos +1; i < get_Block_n_cfgpreds(b); i++) {
1804         ir_node *b_pred = get_nodes_Block(get_Block_cfgpred(b, i));
1805         if (is_pred_of(b_pred, pred)) dispensable = 0;
1806       }
1807       if (!dispensable) {
1808         set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
1809         n_preds = 1;
1810       } else {
1811         n_preds = get_Block_n_cfgpreds(pred);
1812       }
1813     }
1814   }
1815
1816   return n_preds;
1817 }
1818
1819 static void optimize_blocks(ir_node *b, void *env) {
1820   int i, j, k, max_preds, n_preds;
1821   ir_node *pred, *phi;
1822   ir_node **in;
1823
1824   /* Count the number of predecessor if this block is merged with pred blocks
1825      that are empty. */
1826   max_preds = 0;
1827   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1828     max_preds += test_whether_dispensable(b, i);
1829   }
1830   in = (ir_node **) malloc(max_preds * sizeof(ir_node *));
1831
1832 /*-
1833   printf(" working on "); DDMN(b);
1834   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1835     pred = get_nodes_Block(get_Block_cfgpred(b, i));
1836     if (is_Bad(get_Block_cfgpred(b, i))) {
1837       printf("  removing Bad %i\n ", i);
1838     } else if (get_Block_block_visited(pred) +1
1839            < get_irg_block_visited(current_ir_graph)) {
1840       printf("  removing pred %i ", i); DDMN(pred);
1841     } else { printf("  Nothing to do for "); DDMN(pred); }
1842   }
1843   * end Debug output -*/
1844
1845   /*- Fix the Phi nodes -*/
1846   phi = get_irn_link(b);
1847   while (phi) {
1848     assert(get_irn_op(phi) == op_Phi);
1849     /* Find the new predecessors for the Phi */
1850     n_preds = 0;
1851     for (i = 0; i < get_Block_n_cfgpreds(b); 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         ir_node *phi_pred = get_Phi_pred(phi, i);
1859         for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
1860           if (get_nodes_Block(phi_pred) == pred) {
1861             assert(get_irn_op(phi_pred) == op_Phi);  /* Block is empty!! */
1862             in[n_preds] = get_Phi_pred(phi_pred, j);
1863           } else {
1864             in[n_preds] = phi_pred;
1865           }
1866           n_preds++;
1867         }
1868         /* The Phi_pred node is replaced now if it is a Phi.
1869            In Schleifen kann offenbar der entfernte Phi Knoten legal verwendet werden.
1870            Daher muss der Phiknoten durch den neuen ersetzt werden.
1871            Weiter muss der alte Phiknoten entfernt werden (durch ersetzen oder
1872            durch einen Bad) damit er aus den keep_alive verschwinden kann.
1873            Man sollte also, falls keine Schleife vorliegt, exchange mit new_Bad
1874            aufrufen.  */
1875         if (get_nodes_Block(phi_pred) == pred) {
1876           /* remove the Phi as it might be kept alive. Further there
1877              might be other users. */
1878           exchange(phi_pred, phi);  /* geht, ist aber doch semantisch falsch! Warum?? */
1879         }
1880       } else {
1881         in[n_preds] = get_Phi_pred(phi, i);
1882         n_preds ++;
1883       }
1884     }
1885     /* Fix the node */
1886     set_irn_in(phi, n_preds, in);
1887
1888     phi = get_irn_link(phi);
1889   }
1890
1891   /*- This happens only if merge between loop backedge and single loop entry. -*/
1892   for (k = 0; k < get_Block_n_cfgpreds(b); k++) {
1893     pred = get_nodes_Block(get_Block_cfgpred(b, k));
1894     if (get_Block_block_visited(pred)+1 < get_irg_block_visited(current_ir_graph)) {
1895       phi = get_irn_link(pred);
1896       while (phi) {
1897         if (get_irn_op(phi) == op_Phi) {
1898           set_nodes_Block(phi, b);
1899
1900           n_preds = 0;
1901           for (i = 0; i < k; 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               for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
1909                 /* @@@ Hier brauche ich Schleifeninformation!!! Kontrollflusskante
1910                    muss Rueckwaertskante sein! (An allen vier in[n_preds] = phi
1911                    Anweisungen.) Trotzdem tuts bisher!! */
1912                 in[n_preds] = phi;
1913                 n_preds++;
1914               }
1915             } else {
1916               in[n_preds] = phi;
1917               n_preds++;
1918             }
1919           }
1920           for (i = 0; i < get_Phi_n_preds(phi); i++) {
1921             in[n_preds] = get_Phi_pred(phi, i);
1922             n_preds++;
1923           }
1924           for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
1925             pred = get_nodes_Block(get_Block_cfgpred(b, i));
1926             if (is_Bad(get_Block_cfgpred(b, i))) {
1927               /* Do nothing */
1928             } else if (get_Block_block_visited(pred) +1
1929                        < get_irg_block_visited(current_ir_graph)) {
1930               /* It's an empty block and not yet visited. */
1931               for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
1932                 in[n_preds] = phi;
1933                 n_preds++;
1934               }
1935             } else {
1936               in[n_preds] = phi;
1937               n_preds++;
1938             }
1939           }
1940           set_irn_in(phi, n_preds, in);
1941         }
1942         phi = get_irn_link(phi);
1943       }
1944     }
1945   }
1946
1947   /*- Fix the block -*/
1948   n_preds = 0;
1949   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
1950     pred = get_nodes_Block(get_Block_cfgpred(b, i));
1951     if (is_Bad(get_Block_cfgpred(b, i))) {
1952       /* Do nothing */
1953     } else if (get_Block_block_visited(pred) +1
1954            < get_irg_block_visited(current_ir_graph)) {
1955       /* It's an empty block and not yet visited. */
1956       assert(get_Block_n_cfgpreds(b) > 1);
1957                         /* Else it should be optimized by equivalent_node. */
1958       for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
1959         in[n_preds] = get_Block_cfgpred(pred, j);
1960         n_preds++;
1961       }
1962       /* Remove block as it might be kept alive. */
1963       exchange(pred, b/*new_Bad()*/);
1964     } else {
1965       in[n_preds] = get_Block_cfgpred(b, i);
1966       n_preds ++;
1967     }
1968   }
1969   set_irn_in(b, n_preds, in);
1970   free(in);
1971 }
1972
1973 /**
1974  * an impossible ir_node * != NULL
1975  */
1976 static const char _anchor;
1977 #define ANCHOR  ((ir_node *)&_anchor)
1978
1979 /**
1980  * optimize constant cond with projs
1981  *
1982  * If we come here, we should have 3 situations:
1983  *
1984  * 1.) Only one Proj exists: This should be the default Proj, convert to jump
1985  * 2.) Two Proj's exists: One is the taken, the other the not-taken default proj
1986  * 3.) More than 2 Proj's: local_optimize() did not run or internal error do nothing
1987  */
1988 static void optimize_const_conds(ir_node *cond_list)
1989 {
1990   ir_node *cond, *next;
1991
1992   for (cond = cond_list; cond != ANCHOR; cond = next) {
1993     ir_node *block, *jmp;
1994     ir_node *proj = NULL, *def_proj = NULL;
1995     int num = 0;
1996
1997     for (next = get_irn_link(cond); next != ANCHOR; next = get_irn_link(next)) {
1998       if (get_irn_op(next) == op_Cond)
1999         break;
2000
2001       assert(get_irn_op(next) == op_Proj && "something neither Cond not Proj in cond-list");
2002       assert(get_Proj_pred(next) == cond && "cond-list corrupt");
2003
2004       if (get_Proj_proj(next) == get_Cond_defaultProj(cond))
2005         def_proj = next;
2006       else
2007         proj = next;
2008       ++num;
2009     }
2010
2011     if (num == 1) {
2012       assert(def_proj);
2013
2014       block = get_nodes_block(def_proj);
2015       jmp = new_rd_Jmp(get_irn_dbg_info(def_proj), current_ir_graph, block);
2016       exchange(def_proj, jmp);
2017     }
2018     else if (num == 2) {
2019       assert(def_proj && proj);
2020
2021       exchange(def_proj, new_Bad());
2022
2023       block = get_nodes_block(proj);
2024       jmp = new_rd_Jmp(get_irn_dbg_info(proj), current_ir_graph, block);
2025       exchange(proj, jmp);
2026     }
2027   }
2028 }
2029
2030 void optimize_cf(ir_graph *irg) {
2031   int i;
2032   ir_node **in;
2033   ir_node *end = get_irg_end(irg);
2034   ir_graph *rem = current_ir_graph;
2035   current_ir_graph = irg;
2036   ir_node *cond_list = ANCHOR;
2037
2038   /* Handle graph state */
2039   assert(get_irg_phase_state(irg) != phase_building);
2040   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
2041     set_irg_outs_inconsistent(current_ir_graph);
2042   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
2043     set_irg_dom_inconsistent(current_ir_graph);
2044
2045   /* Use block visited flag to mark non-empty blocks. */
2046   inc_irg_block_visited(irg);
2047   irg_walk(end, merge_blocks, collect_nodes, &cond_list);
2048
2049   /* now, optimize switches */
2050   if (get_opt_unreachable_code())
2051     optimize_const_conds(cond_list);
2052
2053   /* Optimize the standard code. */
2054   irg_block_walk(get_irg_end_block(irg), optimize_blocks, NULL, NULL);
2055
2056   /* Walk all keep alives, optimize them if block, add to new in-array
2057      for end if useful. */
2058   in = NEW_ARR_F (ir_node *, 1);
2059   in[0] = get_nodes_Block(end);
2060   inc_irg_visited(current_ir_graph);
2061   for(i = 0; i < get_End_n_keepalives(end); i++) {
2062     ir_node *ka = get_End_keepalive(end, i);
2063     if (irn_not_visited(ka)) {
2064       if ((get_irn_op(ka) == op_Block) && Block_not_block_visited(ka)) {
2065         set_irg_block_visited(current_ir_graph,  /* Don't walk all the way to Start. */
2066                               get_irg_block_visited(current_ir_graph)-1);
2067         irg_block_walk(ka, optimize_blocks, NULL, NULL);
2068         mark_irn_visited(ka);
2069         ARR_APP1 (ir_node *, in, ka);
2070       } else if (get_irn_op(ka) == op_Phi) {
2071         mark_irn_visited(ka);
2072         ARR_APP1 (ir_node *, in, ka);
2073       }
2074     }
2075   }
2076   /* DEL_ARR_F(end->in);   GL @@@ tut nicht ! */
2077   end->in = in;
2078
2079   current_ir_graph = rem;
2080 }
2081
2082
2083 /**
2084  * Called by walker of remove_critical_cf_edges().
2085  *
2086  * Place an empty block to an edge between a blocks of multiple
2087  * predecessors and a block of multiple successors.
2088  *
2089  * @param n IR node
2090  * @param env Environment of walker. This field is unused and has
2091  *            the value NULL.
2092  */
2093 static void walk_critical_cf_edges(ir_node *n, void *env) {
2094   int arity, i;
2095   ir_node *pre, *block, **in, *jmp;
2096
2097   arity = get_irn_arity(n);
2098
2099   /* Block has multiple predecessors */
2100   if (op_Block == get_irn_op(n) && arity > 1) {
2101
2102     if (n == get_irg_end_block(current_ir_graph))
2103       return;  /*  No use to add a block here.      */
2104
2105     for (i = 0; i < arity; ++i) {
2106       pre = get_irn_n(n, i);
2107       /* Predecessor has multiple successors. Insert new flow edge */
2108       if ((NULL != pre) &&
2109         (op_Proj == get_irn_op(pre)) &&
2110         op_Raise != get_irn_op(skip_Proj(pre))) {
2111
2112         /* set predecessor array for new block */
2113         in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 1);
2114         /* set predecessor of new block */
2115         in[0] = pre;
2116         block = new_Block(1, in);
2117         /* insert new jmp node to new block */
2118         switch_block(block);
2119         jmp = new_Jmp();
2120         switch_block(n);
2121         /* set successor of new block */
2122         set_irn_n(n, i, jmp);
2123
2124       } /* predecessor has multiple successors */
2125     } /* for all predecessors */
2126   } /* n is a block */
2127 }
2128
2129 void remove_critical_cf_edges(ir_graph *irg) {
2130   if (get_opt_critical_edges())
2131     irg_walk_graph(irg, NULL, walk_critical_cf_edges, NULL);
2132 }