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