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