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