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