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