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