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