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