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