add an option to disable calling convention optimisation
[libfirm] / ir / ir / irgopt.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief    Optimizations for a whole ir graph, i.e., a procedure.
23  * @author   Christian Schaefer, Goetz Lindenmaier, Sebastian Felis,
24  *           Michael Beck
25  * @version  $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <assert.h>
32
33 #include "irnode_t.h"
34 #include "irgraph_t.h"
35 #include "irprog_t.h"
36
37 #include "iroptimize.h"
38 #include "ircons_t.h"
39 #include "iropt_t.h"
40 #include "irgopt.h"
41 #include "irgmod.h"
42 #include "irgwalk.h"
43
44 #include "array.h"
45 #include "pset.h"
46 #include "pmap.h"
47 #include "pdeq.h"       /* Fuer code placement */
48 #include "xmalloc.h"
49
50 #include "irouts.h"
51 #include "irloop_t.h"
52 #include "irbackedge_t.h"
53 #include "cgana.h"
54 #include "trouts.h"
55
56
57 #include "irflag_t.h"
58 #include "irhooks.h"
59 #include "iredges_t.h"
60 #include "irtools.h"
61
62 /*------------------------------------------------------------------*/
63 /* apply optimizations of iropt to all nodes.                       */
64 /*------------------------------------------------------------------*/
65
66 /**
67  * A wrapper around optimize_inplace_2() to be called from a walker.
68  */
69 static void optimize_in_place_wrapper (ir_node *n, void *env) {
70         ir_node *optimized = optimize_in_place_2(n);
71         (void) env;
72
73         if (optimized != n) {
74                 exchange (n, optimized);
75         }
76 }
77
78 /**
79  * Do local optimizations for a node.
80  *
81  * @param n  the IR-node where to start. Typically the End node
82  *           of a graph
83  *
84  * @note current_ir_graph must be set
85  */
86 static INLINE void do_local_optimize(ir_node *n) {
87         /* Handle graph state */
88         assert(get_irg_phase_state(current_ir_graph) != phase_building);
89
90         if (get_opt_global_cse())
91         set_irg_pinned(current_ir_graph, op_pin_state_floats);
92         set_irg_outs_inconsistent(current_ir_graph);
93         set_irg_doms_inconsistent(current_ir_graph);
94         set_irg_loopinfo_inconsistent(current_ir_graph);
95
96         /* Clean the value_table in irg for the CSE. */
97         del_identities(current_ir_graph->value_table);
98         current_ir_graph->value_table = new_identities();
99
100         /* walk over the graph */
101         irg_walk(n, firm_clear_link, optimize_in_place_wrapper, NULL);
102 }
103
104 /* Applies local optimizations (see iropt.h) to all nodes reachable from node n */
105 void local_optimize_node(ir_node *n) {
106         ir_graph *rem = current_ir_graph;
107         current_ir_graph = get_irn_irg(n);
108
109         do_local_optimize(n);
110
111         current_ir_graph = rem;
112 }
113
114 /**
115  * Block-Walker: uses dominance depth to mark dead blocks.
116  */
117 static void kill_dead_blocks(ir_node *block, void *env) {
118         (void) env;
119
120         if (get_Block_dom_depth(block) < 0) {
121                 /*
122                  * Note that the new dominance code correctly handles
123                  * the End block, i.e. it is always reachable from Start
124                  */
125                 set_Block_dead(block);
126         }
127 }
128
129 /* Applies local optimizations (see iropt.h) to all nodes reachable from node n. */
130 void local_optimize_graph(ir_graph *irg) {
131         ir_graph *rem = current_ir_graph;
132         current_ir_graph = irg;
133
134         if (get_irg_dom_state(irg) == dom_consistent)
135                 irg_block_walk_graph(irg, NULL, kill_dead_blocks, NULL);
136
137         do_local_optimize(get_irg_end(irg));
138
139         current_ir_graph = rem;
140 }
141
142 /**
143  * Enqueue all users of a node to a wait queue.
144  * Handles mode_T nodes.
145  */
146 static void enqueue_users(ir_node *n, pdeq *waitq) {
147         const ir_edge_t *edge;
148
149         foreach_out_edge(n, edge) {
150                 ir_node *succ = get_edge_src_irn(edge);
151
152                 if (get_irn_link(succ) != waitq) {
153                         pdeq_putr(waitq, succ);
154                         set_irn_link(succ, waitq);
155                 }
156                 if (get_irn_mode(succ) == mode_T) {
157                 /* A mode_T node has Proj's. Because most optimizations
158                         run on the Proj's we have to enqueue them also. */
159                         enqueue_users(succ, waitq);
160                 }
161         }
162 }
163
164 /**
165  * Data flow optimization walker.
166  * Optimizes all nodes and enqueue it's users
167  * if done.
168  */
169 static void opt_walker(ir_node *n, void *env) {
170         pdeq *waitq = env;
171         ir_node *optimized;
172
173         optimized = optimize_in_place_2(n);
174         set_irn_link(optimized, NULL);
175
176         if (optimized != n) {
177                 enqueue_users(n, waitq);
178                 exchange(n, optimized);
179         }
180 }
181
182 /* Applies local optimizations to all nodes in the graph until fixpoint. */
183 void optimize_graph_df(ir_graph *irg) {
184         pdeq     *waitq = new_pdeq();
185         int      state = edges_activated(irg);
186         ir_graph *rem = current_ir_graph;
187         ir_node  *end;
188         int      i;
189
190         current_ir_graph = irg;
191
192         if (! state)
193                 edges_activate(irg);
194
195         if (get_opt_global_cse())
196                 set_irg_pinned(current_ir_graph, op_pin_state_floats);
197
198         /* Clean the value_table in irg for the CSE. */
199         del_identities(irg->value_table);
200         irg->value_table = new_identities();
201
202         if (get_irg_dom_state(irg) == dom_consistent)
203                 irg_block_walk_graph(irg, NULL, kill_dead_blocks, NULL);
204
205         /* invalidate info */
206         set_irg_outs_inconsistent(irg);
207         set_irg_doms_inconsistent(irg);
208         set_irg_loopinfo_inconsistent(irg);
209
210         set_using_irn_link(irg);
211
212         /* walk over the graph, but don't touch keep-alives */
213         irg_walk(get_irg_end_block(irg), NULL, opt_walker, waitq);
214
215         end = get_irg_end(irg);
216
217         /* optimize keep-alives by removing superfluous ones */
218         for (i = get_End_n_keepalives(end) - 1; i >= 0; --i) {
219                 ir_node *ka = get_End_keepalive(end, i);
220
221                 if (irn_visited(ka) && !is_irn_keep(ka)) {
222                         /* this node can be regularly visited, no need to keep it */
223                         set_End_keepalive(end, i, get_irg_bad(irg));
224                 }
225         }
226         /* now walk again and visit all not yet visited nodes */
227         set_irg_visited(current_ir_graph, get_irg_visited(irg) - 1);
228         irg_walk(get_irg_end(irg), NULL, opt_walker, waitq);
229
230         /* finish the wait queue */
231         while (! pdeq_empty(waitq)) {
232                 ir_node *n = pdeq_getl(waitq);
233                 if (! is_Bad(n))
234                         opt_walker(n, waitq);
235         }
236
237         del_pdeq(waitq);
238
239         clear_using_irn_link(irg);
240
241         if (! state)
242                 edges_deactivate(irg);
243
244         current_ir_graph = rem;
245 }
246
247
248 /*------------------------------------------------------------------*/
249 /* Routines for dead node elimination / copying garbage collection  */
250 /* of the obstack.                                                  */
251 /*------------------------------------------------------------------*/
252
253 /**
254  * Remember the new node in the old node by using a field all nodes have.
255  */
256 #define set_new_node(oldn, newn)  set_irn_link(oldn, newn)
257
258 /**
259  * Get this new node, before the old node is forgotten.
260  */
261 #define get_new_node(oldn) get_irn_link(oldn)
262
263 /**
264  * Check if a new node was set.
265  */
266 #define has_new_node(n) (get_new_node(n) != NULL)
267
268 /**
269  * We use the block_visited flag to mark that we have computed the
270  * number of useful predecessors for this block.
271  * Further we encode the new arity in this flag in the old blocks.
272  * Remembering the arity is useful, as it saves a lot of pointer
273  * accesses.  This function is called for all Phi and Block nodes
274  * in a Block.
275  */
276 static INLINE int
277 compute_new_arity(ir_node *b) {
278         int i, res, irn_arity;
279         int irg_v, block_v;
280
281         irg_v = get_irg_block_visited(current_ir_graph);
282         block_v = get_Block_block_visited(b);
283         if (block_v >= irg_v) {
284                 /* we computed the number of preds for this block and saved it in the
285                    block_v flag */
286                 return block_v - irg_v;
287         } else {
288                 /* compute the number of good predecessors */
289                 res = irn_arity = get_irn_arity(b);
290                 for (i = 0; i < irn_arity; i++)
291                         if (get_irn_opcode(get_irn_n(b, i)) == iro_Bad) res--;
292                         /* save it in the flag. */
293                         set_Block_block_visited(b, irg_v + res);
294                         return res;
295         }
296 }
297
298 /**
299  * Copies the node to the new obstack. The Ins of the new node point to
300  * the predecessors on the old obstack.  For block/phi nodes not all
301  * predecessors might be copied.  n->link points to the new node.
302  * For Phi and Block nodes the function allocates in-arrays with an arity
303  * only for useful predecessors.  The arity is determined by counting
304  * the non-bad predecessors of the block.
305  *
306  * @param n    The node to be copied
307  * @param env  if non-NULL, the node number attribute will be copied to the new node
308  *
309  * Note: Also used for loop unrolling.
310  */
311 static void copy_node(ir_node *n, void *env) {
312         ir_node *nn, *block;
313         int new_arity;
314         ir_op *op = get_irn_op(n);
315
316         /* The end node looses it's flexible in array.  This doesn't matter,
317            as dead node elimination builds End by hand, inlineing doesn't use
318            the End node. */
319         /* assert(op == op_End ||  ((_ARR_DESCR(n->in))->cookie != ARR_F_MAGIC)); */
320
321         if (op == op_Bad) {
322                 /* node copied already */
323                 return;
324         } else if (op == op_Block) {
325                 block = NULL;
326                 new_arity = compute_new_arity(n);
327                 n->attr.block.graph_arr = NULL;
328         } else {
329                 block = get_nodes_block(n);
330                 if (op == op_Phi) {
331                         new_arity = compute_new_arity(block);
332                 } else {
333                         new_arity = get_irn_arity(n);
334                 }
335         }
336         nn = new_ir_node(get_irn_dbg_info(n),
337                 current_ir_graph,
338                 block,
339                 op,
340                 get_irn_mode(n),
341                 new_arity,
342                 get_irn_in(n) + 1);
343                 /* Copy the attributes.  These might point to additional data.  If this
344                 was allocated on the old obstack the pointers now are dangling.  This
345         frees e.g. the memory of the graph_arr allocated in new_immBlock. */
346         copy_node_attr(n, nn);
347
348 #ifdef DEBUG_libfirm
349         {
350                 int copy_node_nr = env != NULL;
351                 if (copy_node_nr) {
352                         /* for easier debugging, we want to copy the node numbers too */
353                         nn->node_nr = n->node_nr;
354                 }
355         }
356 #endif
357
358         set_new_node(n, nn);
359         hook_dead_node_elim_subst(current_ir_graph, n, nn);
360 }
361
362 /**
363  * Copies new predecessors of old node to new node remembered in link.
364  * Spare the Bad predecessors of Phi and Block nodes.
365  */
366 static void copy_preds(ir_node *n, void *env) {
367         ir_node *nn, *block;
368         int i, j, irn_arity;
369         (void) env;
370
371         nn = get_new_node(n);
372
373         if (is_Block(n)) {
374                 /* copy the macro block header */
375                 ir_node *mbh = get_Block_MacroBlock(n);
376
377                 if (mbh == n) {
378                         /* this block is a macroblock header */
379                         set_irn_n(nn, -1, nn);
380                 } else {
381                         /* get the macro block header */
382                         set_irn_n(nn, -1, get_new_node(mbh));
383                 }
384
385                 /* Don't copy Bad nodes. */
386                 j = 0;
387                 irn_arity = get_irn_arity(n);
388                 for (i = 0; i < irn_arity; i++) {
389                         if (! is_Bad(get_irn_n(n, i))) {
390                                 set_irn_n(nn, j, get_new_node(get_irn_n(n, i)));
391                                 /*if (is_backedge(n, i)) set_backedge(nn, j);*/
392                                 j++;
393                         }
394                 }
395                 /* repair the block visited flag from above misuse. Repair it in both
396                    graphs so that the old one can still be used. */
397                 set_Block_block_visited(nn, 0);
398                 set_Block_block_visited(n, 0);
399                 /* Local optimization could not merge two subsequent blocks if
400                    in array contained Bads.  Now it's possible.
401                    We don't call optimize_in_place as it requires
402                    that the fields in ir_graph are set properly. */
403                 if ((get_opt_control_flow_straightening()) &&
404                         (get_Block_n_cfgpreds(nn) == 1) &&
405                         (get_irn_op(get_Block_cfgpred(nn, 0)) == op_Jmp)) {
406                         ir_node *old = get_nodes_block(get_Block_cfgpred(nn, 0));
407                         if (nn == old) {
408                                 /* Jmp jumps into the block it is in -- deal self cycle. */
409                                 assert(is_Bad(get_new_node(get_irg_bad(current_ir_graph))));
410                                 exchange(nn, get_new_node(get_irg_bad(current_ir_graph)));
411                         } else {
412                                 exchange(nn, old);
413                         }
414                 }
415         } else if (is_Phi(n)) {
416                 /* Don't copy node if corresponding predecessor in block is Bad.
417                    The Block itself should not be Bad. */
418                 block = get_nodes_block(n);
419                 set_irn_n(nn, -1, get_new_node(block));
420                 j = 0;
421                 irn_arity = get_irn_arity(n);
422                 for (i = 0; i < irn_arity; i++) {
423                         if (! is_Bad(get_irn_n(block, i))) {
424                                 set_irn_n(nn, j, get_new_node(get_irn_n(n, i)));
425                                 /*if (is_backedge(n, i)) set_backedge(nn, j);*/
426                                 j++;
427                         }
428                 }
429                 /* If the pre walker reached this Phi after the post walker visited the
430                    block block_visited is > 0. */
431                 set_Block_block_visited(get_nodes_block(n), 0);
432                 /* Compacting the Phi's ins might generate Phis with only one
433                    predecessor. */
434                 if (get_irn_arity(nn) == 1)
435                         exchange(nn, get_irn_n(nn, 0));
436         } else {
437                 irn_arity = get_irn_arity(n);
438                 for (i = -1; i < irn_arity; i++)
439                         set_irn_n (nn, i, get_new_node(get_irn_n(n, i)));
440         }
441         /* Now the new node is complete.  We can add it to the hash table for CSE.
442            @@@ inlining aborts if we identify End. Why? */
443         if (get_irn_op(nn) != op_End)
444                 add_identities(current_ir_graph->value_table, nn);
445 }
446
447 /**
448  * Copies the graph recursively, compacts the keep-alives of the end node.
449  *
450  * @param irg           the graph to be copied
451  * @param copy_node_nr  If non-zero, the node number will be copied
452  */
453 static void copy_graph(ir_graph *irg, int copy_node_nr) {
454         ir_node *oe, *ne, *ob, *nb, *om, *nm; /* old end, new end, old bad, new bad, old NoMem, new NoMem */
455         ir_node *ka;      /* keep alive */
456         int i, irn_arity;
457         unsigned long vfl;
458
459         /* Some nodes must be copied by hand, sigh */
460         vfl = get_irg_visited(irg);
461         set_irg_visited(irg, vfl + 1);
462
463         oe = get_irg_end(irg);
464         mark_irn_visited(oe);
465         /* copy the end node by hand, allocate dynamic in array! */
466         ne = new_ir_node(get_irn_dbg_info(oe),
467                 irg,
468                 NULL,
469                 op_End,
470                 mode_X,
471                 -1,
472                 NULL);
473         /* Copy the attributes.  Well, there might be some in the future... */
474         copy_node_attr(oe, ne);
475         set_new_node(oe, ne);
476
477         /* copy the Bad node */
478         ob = get_irg_bad(irg);
479         mark_irn_visited(ob);
480         nb = new_ir_node(get_irn_dbg_info(ob),
481                 irg,
482                 NULL,
483                 op_Bad,
484                 mode_T,
485                 0,
486                 NULL);
487         copy_node_attr(ob, nb);
488         set_new_node(ob, nb);
489
490         /* copy the NoMem node */
491         om = get_irg_no_mem(irg);
492         mark_irn_visited(om);
493         nm = new_ir_node(get_irn_dbg_info(om),
494                 irg,
495                 NULL,
496                 op_NoMem,
497                 mode_M,
498                 0,
499                 NULL);
500         copy_node_attr(om, nm);
501         set_new_node(om, nm);
502
503         /* copy the live nodes */
504         set_irg_visited(irg, vfl);
505         irg_walk(get_nodes_block(oe), copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
506
507         /* Note: from yet, the visited flag of the graph is equal to vfl + 1 */
508
509         /* visit the anchors as well */
510         for (i = get_irg_n_anchors(irg) - 1; i >= 0; --i) {
511                 ir_node *n = get_irg_anchor(irg, i);
512
513                 if (n && (get_irn_visited(n) <= vfl)) {
514                         set_irg_visited(irg, vfl);
515                         irg_walk(n, copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
516                 }
517         }
518
519         /* copy_preds for the end node ... */
520         set_nodes_block(ne, get_new_node(get_nodes_block(oe)));
521
522         /*- ... and now the keep alives. -*/
523         /* First pick the not marked block nodes and walk them.  We must pick these
524            first as else we will oversee blocks reachable from Phis. */
525         irn_arity = get_End_n_keepalives(oe);
526         for (i = 0; i < irn_arity; i++) {
527                 ka = get_End_keepalive(oe, i);
528                 if (is_Block(ka)) {
529                         if (get_irn_visited(ka) <= vfl) {
530                                 /* We must keep the block alive and copy everything reachable */
531                                 set_irg_visited(irg, vfl);
532                                 irg_walk(ka, copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
533                         }
534                         add_End_keepalive(ne, get_new_node(ka));
535                 }
536         }
537
538         /* Now pick other nodes.  Here we will keep all! */
539         irn_arity = get_End_n_keepalives(oe);
540         for (i = 0; i < irn_arity; i++) {
541                 ka = get_End_keepalive(oe, i);
542                 if (!is_Block(ka)) {
543                         if (get_irn_visited(ka) <= vfl) {
544                                 /* We didn't copy the node yet.  */
545                                 set_irg_visited(irg, vfl);
546                                 irg_walk(ka, copy_node, copy_preds, INT_TO_PTR(copy_node_nr));
547                         }
548                         add_End_keepalive(ne, get_new_node(ka));
549                 }
550         }
551
552         /* start block sometimes only reached after keep alives */
553         set_nodes_block(nb, get_new_node(get_nodes_block(ob)));
554         set_nodes_block(nm, get_new_node(get_nodes_block(om)));
555 }
556
557 /**
558  * Copies the graph reachable from current_ir_graph->end to the obstack
559  * in current_ir_graph and fixes the environment.
560  * Then fixes the fields in current_ir_graph containing nodes of the
561  * graph.
562  *
563  * @param copy_node_nr  If non-zero, the node number will be copied
564  */
565 static void
566 copy_graph_env(int copy_node_nr) {
567         ir_graph *irg = current_ir_graph;
568         ir_node *old_end, *new_anchor;
569         int i;
570
571         /* remove end_except and end_reg nodes */
572         old_end = get_irg_end(irg);
573         set_irg_end_except (irg, old_end);
574         set_irg_end_reg    (irg, old_end);
575
576         /* Not all nodes remembered in irg might be reachable
577            from the end node.  Assure their link is set to NULL, so that
578            we can test whether new nodes have been computed. */
579         for (i = get_irg_n_anchors(irg) - 1; i >= 0; --i) {
580                 ir_node *n = get_irg_anchor(irg, i);
581                 if (n != NULL)
582                         set_new_node(n, NULL);
583         }
584         /* we use the block walk flag for removing Bads from Blocks ins. */
585         inc_irg_block_visited(irg);
586
587         /* copy the graph */
588         copy_graph(irg, copy_node_nr);
589
590         /* fix the anchor */
591         old_end    = get_irg_end(irg);
592         new_anchor = new_Anchor(irg);
593
594         for (i = get_irg_n_anchors(irg) - 1; i >= 0; --i) {
595                 ir_node *n = get_irg_anchor(irg, i);
596                 if (n)
597                         set_irn_n(new_anchor, i, get_new_node(n));
598         }
599         free_End(old_end);
600         irg->anchor = new_anchor;
601
602         /* ensure the new anchor is placed in the endblock */
603         set_irn_n(new_anchor, -1, get_irg_end_block(irg));
604 }
605
606 /**
607  * Copies all reachable nodes to a new obstack.  Removes bad inputs
608  * from block nodes and the corresponding inputs from Phi nodes.
609  * Merges single exit blocks with single entry blocks and removes
610  * 1-input Phis.
611  * Adds all new nodes to a new hash table for CSE.  Does not
612  * perform CSE, so the hash table might contain common subexpressions.
613  */
614 void
615 dead_node_elimination(ir_graph *irg) {
616         if (get_opt_optimize() && get_opt_dead_node_elimination()) {
617                 ir_graph *rem;
618                 int rem_ipview = get_interprocedural_view();
619                 struct obstack *graveyard_obst = NULL;
620                 struct obstack *rebirth_obst   = NULL;
621                 assert(! edges_activated(irg) && "dead node elimination requires disabled edges");
622
623                 /* inform statistics that we started a dead-node elimination run */
624                 hook_dead_node_elim(irg, 1);
625
626                 /* Remember external state of current_ir_graph. */
627                 rem = current_ir_graph;
628                 current_ir_graph = irg;
629                 set_interprocedural_view(0);
630
631                 assert(get_irg_phase_state(irg) != phase_building);
632
633                 /* Handle graph state */
634                 free_callee_info(irg);
635                 free_irg_outs(irg);
636                 free_trouts();
637
638                 /* @@@ so far we loose loops when copying */
639                 free_loop_information(irg);
640
641                 set_irg_doms_inconsistent(irg);
642
643                 /* A quiet place, where the old obstack can rest in peace,
644                    until it will be cremated. */
645                 graveyard_obst = irg->obst;
646
647                 /* A new obstack, where the reachable nodes will be copied to. */
648                 rebirth_obst = xmalloc(sizeof(*rebirth_obst));
649                 irg->obst = rebirth_obst;
650                 obstack_init(irg->obst);
651                 irg->last_node_idx = 0;
652
653                 /* We also need a new value table for CSE */
654                 del_identities(irg->value_table);
655                 irg->value_table = new_identities();
656
657                 /* Copy the graph from the old to the new obstack */
658                 copy_graph_env(/*copy_node_nr=*/1);
659
660                 /* Free memory from old unoptimized obstack */
661                 obstack_free(graveyard_obst, 0);  /* First empty the obstack ... */
662                 xfree(graveyard_obst);            /* ... then free it.           */
663
664                 /* inform statistics that the run is over */
665                 hook_dead_node_elim(irg, 0);
666
667                 current_ir_graph = rem;
668                 set_interprocedural_view(rem_ipview);
669         }
670 }
671
672 /**
673  * Relink bad predecessors of a block and store the old in array to the
674  * link field. This function is called by relink_bad_predecessors().
675  * The array of link field starts with the block operand at position 0.
676  * If block has bad predecessors, create a new in array without bad preds.
677  * Otherwise let in array untouched.
678  */
679 static void relink_bad_block_predecessors(ir_node *n, void *env) {
680         ir_node **new_in, *irn;
681         int i, new_irn_n, old_irn_arity, new_irn_arity = 0;
682         (void) env;
683
684         /* if link field of block is NULL, look for bad predecessors otherwise
685            this is already done */
686         if (get_irn_op(n) == op_Block &&
687                 get_irn_link(n) == NULL) {
688
689                 /* save old predecessors in link field (position 0 is the block operand)*/
690                 set_irn_link(n, get_irn_in(n));
691
692                 /* count predecessors without bad nodes */
693                 old_irn_arity = get_irn_arity(n);
694                 for (i = 0; i < old_irn_arity; i++)
695                         if (!is_Bad(get_irn_n(n, i))) new_irn_arity++;
696
697                         /* arity changing: set new predecessors without bad nodes */
698                         if (new_irn_arity < old_irn_arity) {
699                                 /* Get new predecessor array. We do not resize the array, as we must
700                                    keep the old one to update Phis. */
701                                 new_in = NEW_ARR_D (ir_node *, current_ir_graph->obst, (new_irn_arity+1));
702
703                                 /* set new predecessors in array */
704                                 new_in[0] = NULL;
705                                 new_irn_n = 1;
706                                 for (i = 0; i < old_irn_arity; i++) {
707                                         irn = get_irn_n(n, i);
708                                         if (!is_Bad(irn)) {
709                                                 new_in[new_irn_n] = irn;
710                                                 is_backedge(n, i) ? set_backedge(n, new_irn_n-1) : set_not_backedge(n, new_irn_n-1);
711                                                 ++new_irn_n;
712                                         }
713                                 }
714                                 /* ARR_SETLEN(int, n->attr.block.backedge, new_irn_arity); */
715                                 ARR_SHRINKLEN(n->attr.block.backedge, new_irn_arity);
716                                 n->in = new_in;
717                         } /* ir node has bad predecessors */
718         } /* Block is not relinked */
719 }
720
721 /**
722  * Relinks Bad predecessors from Blocks and Phis called by walker
723  * remove_bad_predecesors(). If n is a Block, call
724  * relink_bad_block_redecessors(). If n is a Phi-node, call also the relinking
725  * function of Phi's Block. If this block has bad predecessors, relink preds
726  * of the Phi-node.
727  */
728 static void relink_bad_predecessors(ir_node *n, void *env) {
729         ir_node *block, **old_in;
730         int i, old_irn_arity, new_irn_arity;
731
732         /* relink bad predecessors of a block */
733         if (get_irn_op(n) == op_Block)
734                 relink_bad_block_predecessors(n, env);
735
736         /* If Phi node relink its block and its predecessors */
737         if (get_irn_op(n) == op_Phi) {
738
739                 /* Relink predecessors of phi's block */
740                 block = get_nodes_block(n);
741                 if (get_irn_link(block) == NULL)
742                         relink_bad_block_predecessors(block, env);
743
744                 old_in = (ir_node **)get_irn_link(block); /* Of Phi's Block */
745                 old_irn_arity = ARR_LEN(old_in);
746
747                 /* Relink Phi predecessors if count of predecessors changed */
748                 if (old_irn_arity != ARR_LEN(get_irn_in(block))) {
749                         /* set new predecessors in array
750                            n->in[0] remains the same block */
751                         new_irn_arity = 1;
752                         for(i = 1; i < old_irn_arity; i++)
753                                 if (!is_Bad((ir_node *)old_in[i])) {
754                                         n->in[new_irn_arity] = n->in[i];
755                                         is_backedge(n, i) ? set_backedge(n, new_irn_arity) : set_not_backedge(n, new_irn_arity);
756                                         ++new_irn_arity;
757                                 }
758
759                                 ARR_SETLEN(ir_node *, n->in, new_irn_arity);
760                                 ARR_SETLEN(int, n->attr.phi_backedge, new_irn_arity);
761                 }
762         } /* n is a Phi node */
763 }
764
765 /*
766  * Removes Bad Bad predecessors from Blocks and the corresponding
767  * inputs to Phi nodes as in dead_node_elimination but without
768  * copying the graph.
769  * On walking up set the link field to NULL, on walking down call
770  * relink_bad_predecessors() (This function stores the old in array
771  * to the link field and sets a new in array if arity of predecessors
772  * changes).
773  */
774 void remove_bad_predecessors(ir_graph *irg) {
775         irg_walk_graph(irg, firm_clear_link, relink_bad_predecessors, NULL);
776 }
777
778
779 /*
780    __                      _  __ __
781   (_     __    o     _    | \/  |_
782   __)|_| | \_/ | \_/(/_   |_/\__|__
783
784   The following stuff implements a facility that automatically patches
785   registered ir_node pointers to the new node when a dead node elimination occurs.
786 */
787
788 struct _survive_dce_t {
789         struct obstack obst;
790         pmap *places;
791         pmap *new_places;
792         hook_entry_t dead_node_elim;
793         hook_entry_t dead_node_elim_subst;
794 };
795
796 typedef struct _survive_dce_list_t {
797         struct _survive_dce_list_t *next;
798         ir_node **place;
799 } survive_dce_list_t;
800
801 static void dead_node_hook(void *context, ir_graph *irg, int start) {
802         survive_dce_t *sd = context;
803         (void) irg;
804
805         /* Create a new map before the dead node elimination is performed. */
806         if (start) {
807                 sd->new_places = pmap_create_ex(pmap_count(sd->places));
808         } else {
809                 /* Patch back all nodes if dead node elimination is over and something is to be done. */
810                 pmap_destroy(sd->places);
811                 sd->places     = sd->new_places;
812                 sd->new_places = NULL;
813         }
814 }
815
816 /**
817  * Hook called when dead node elimination replaces old by nw.
818  */
819 static void dead_node_subst_hook(void *context, ir_graph *irg, ir_node *old, ir_node *nw) {
820         survive_dce_t *sd = context;
821         survive_dce_list_t *list = pmap_get(sd->places, old);
822         (void) irg;
823
824         /* If the node is to be patched back, write the new address to all registered locations. */
825         if (list) {
826                 survive_dce_list_t *p;
827
828                 for (p = list; p; p = p->next)
829                         *(p->place) = nw;
830
831                 pmap_insert(sd->new_places, nw, list);
832         }
833 }
834
835 /**
836  * Make a new Survive DCE environment.
837  */
838 survive_dce_t *new_survive_dce(void) {
839         survive_dce_t *res = xmalloc(sizeof(res[0]));
840         obstack_init(&res->obst);
841         res->places     = pmap_create();
842         res->new_places = NULL;
843
844         res->dead_node_elim.hook._hook_dead_node_elim = dead_node_hook;
845         res->dead_node_elim.context                   = res;
846         res->dead_node_elim.next                      = NULL;
847
848         res->dead_node_elim_subst.hook._hook_dead_node_elim_subst = dead_node_subst_hook;
849         res->dead_node_elim_subst.context = res;
850         res->dead_node_elim_subst.next    = NULL;
851
852 #ifndef FIRM_ENABLE_HOOKS
853         assert(0 && "need hooks enabled");
854 #endif
855
856         register_hook(hook_dead_node_elim, &res->dead_node_elim);
857         register_hook(hook_dead_node_elim_subst, &res->dead_node_elim_subst);
858         return res;
859 }
860
861 /**
862  * Free a Survive DCE environment.
863  */
864 void free_survive_dce(survive_dce_t *sd) {
865         obstack_free(&sd->obst, NULL);
866         pmap_destroy(sd->places);
867         unregister_hook(hook_dead_node_elim, &sd->dead_node_elim);
868         unregister_hook(hook_dead_node_elim_subst, &sd->dead_node_elim_subst);
869         xfree(sd);
870 }
871
872 /**
873  * Register a node pointer to be patched upon DCE.
874  * When DCE occurs, the node pointer specified by @p place will be
875  * patched to the new address of the node it is pointing to.
876  *
877  * @param sd    The Survive DCE environment.
878  * @param place The address of the node pointer.
879  */
880 void survive_dce_register_irn(survive_dce_t *sd, ir_node **place) {
881         if (*place != NULL) {
882                 ir_node *irn      = *place;
883                 survive_dce_list_t *curr = pmap_get(sd->places, irn);
884                 survive_dce_list_t *nw   = obstack_alloc(&sd->obst, sizeof(nw[0]));
885
886                 nw->next  = curr;
887                 nw->place = place;
888
889                 pmap_insert(sd->places, irn, nw);
890         }
891 }
892
893 /*--------------------------------------------------------------------*/
894 /*  Functionality for inlining                                         */
895 /*--------------------------------------------------------------------*/
896
897 /**
898  * Copy node for inlineing.  Updates attributes that change when
899  * inlineing but not for dead node elimination.
900  *
901  * Copies the node by calling copy_node() and then updates the entity if
902  * it's a local one.  env must be a pointer of the frame type of the
903  * inlined procedure. The new entities must be in the link field of
904  * the entities.
905  */
906 static INLINE void
907 copy_node_inline(ir_node *n, void *env) {
908         ir_node *nn;
909         ir_type *frame_tp = (ir_type *)env;
910
911         copy_node(n, NULL);
912         if (get_irn_op(n) == op_Sel) {
913                 nn = get_new_node (n);
914                 assert(is_Sel(nn));
915                 if (get_entity_owner(get_Sel_entity(n)) == frame_tp) {
916                         set_Sel_entity(nn, get_entity_link(get_Sel_entity(n)));
917                 }
918         } else if (get_irn_op(n) == op_Block) {
919                 nn = get_new_node (n);
920                 nn->attr.block.irg = current_ir_graph;
921         }
922 }
923
924 /**
925  * Walker: checks if P_value_arg_base is used.
926  */
927 static void find_addr(ir_node *node, void *env) {
928         int *allow_inline = env;
929         if (is_Proj(node) && get_irn_op(get_Proj_pred(node)) == op_Start) {
930                 if (get_Proj_proj(node) == pn_Start_P_value_arg_base)
931                         *allow_inline = 0;
932         }
933 }
934
935 /**
936  * Check if we can inline a given call.
937  * Currently, we cannot inline two cases:
938  * - call with compound arguments
939  * - graphs that take the address of a parameter
940  *
941  * check these conditions here
942  */
943 static int can_inline(ir_node *call, ir_graph *called_graph) {
944         ir_type *call_type = get_Call_type(call);
945         int params, ress, i, res;
946         assert(is_Method_type(call_type));
947
948         params = get_method_n_params(call_type);
949         ress   = get_method_n_ress(call_type);
950
951         /* check parameters for compound arguments */
952         for (i = 0; i < params; ++i) {
953                 ir_type *p_type = get_method_param_type(call_type, i);
954
955                 if (is_compound_type(p_type))
956                         return 0;
957         }
958
959         /* check results for compound arguments */
960         for (i = 0; i < ress; ++i) {
961                 ir_type *r_type = get_method_res_type(call_type, i);
962
963                 if (is_compound_type(r_type))
964                         return 0;
965         }
966
967         res = 1;
968         irg_walk_graph(called_graph, find_addr, NULL, &res);
969
970         return res;
971 }
972
973 enum exc_mode {
974            exc_handler    = 0, /**< There is a handler. */
975            exc_to_end     = 1, /**< Branches to End. */
976            exc_no_handler = 2  /**< Exception handling not represented. */
977 };
978
979 /* Inlines a method at the given call site. */
980 int inline_method(ir_node *call, ir_graph *called_graph) {
981         ir_node *pre_call;
982         ir_node *post_call, *post_bl;
983         ir_node *in[pn_Start_max];
984         ir_node *end, *end_bl;
985         ir_node **res_pred;
986         ir_node **cf_pred;
987         ir_node *ret, *phi;
988         int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity;
989         enum exc_mode exc_handling;
990         ir_type *called_frame;
991         irg_inline_property prop = get_irg_inline_property(called_graph);
992
993         if ( (prop < irg_inline_forced) &&
994              (!get_opt_optimize() || !get_opt_inline() || (prop == irg_inline_forbidden))) return 0;
995
996         /* Do not inline variadic functions. */
997         if (get_method_variadicity(get_entity_type(get_irg_entity(called_graph))) == variadicity_variadic)
998                 return 0;
999
1000         assert(get_method_n_params(get_entity_type(get_irg_entity(called_graph))) ==
1001                get_method_n_params(get_Call_type(call)));
1002
1003         /*
1004          * currently, we cannot inline two cases:
1005          * - call with compound arguments
1006          * - graphs that take the address of a parameter
1007          */
1008         if (! can_inline(call, called_graph))
1009                 return 0;
1010
1011         /* --  Turn off optimizations, this can cause problems when allocating new nodes. -- */
1012         rem_opt = get_opt_optimize();
1013         set_optimize(0);
1014
1015         /* Handle graph state */
1016         assert(get_irg_phase_state(current_ir_graph) != phase_building);
1017         assert(get_irg_pinned(current_ir_graph) == op_pin_state_pinned);
1018         assert(get_irg_pinned(called_graph) == op_pin_state_pinned);
1019         set_irg_outs_inconsistent(current_ir_graph);
1020         set_irg_extblk_inconsistent(current_ir_graph);
1021         set_irg_doms_inconsistent(current_ir_graph);
1022         set_irg_loopinfo_inconsistent(current_ir_graph);
1023         set_irg_callee_info_state(current_ir_graph, irg_callee_info_inconsistent);
1024
1025         /* -- Check preconditions -- */
1026         assert(is_Call(call));
1027         /* @@@ does not work for InterfaceIII.java after cgana
1028          assert(get_Call_type(call) == get_entity_type(get_irg_entity(called_graph)));
1029          assert(smaller_type(get_entity_type(get_irg_entity(called_graph)),
1030          get_Call_type(call)));
1031         */
1032         if (called_graph == current_ir_graph) {
1033                 set_optimize(rem_opt);
1034                 return 0;
1035         }
1036
1037         /* here we know we WILL inline, so inform the statistics */
1038         hook_inline(call, called_graph);
1039
1040         /* -- Decide how to handle exception control flow: Is there a handler
1041            for the Call node, or do we branch directly to End on an exception?
1042            exc_handling:
1043            0 There is a handler.
1044            1 Branches to End.
1045            2 Exception handling not represented in Firm. -- */
1046         {
1047                 ir_node *proj, *Mproj = NULL, *Xproj = NULL;
1048                 for (proj = get_irn_link(call); proj; proj = get_irn_link(proj)) {
1049                         long proj_nr = get_Proj_proj(proj);
1050                         if (proj_nr == pn_Call_X_except) Xproj = proj;
1051                         if (proj_nr == pn_Call_M_except) Mproj = proj;
1052                 }
1053                 if      (Mproj) { assert(Xproj); exc_handling = exc_handler; } /*  Mproj           */
1054                 else if (Xproj) {                exc_handling = exc_to_end; } /* !Mproj &&  Xproj   */
1055                 else            {                exc_handling = exc_no_handler; } /* !Mproj && !Xproj   */
1056         }
1057
1058         /* --
1059            the procedure and later replaces the Start node of the called graph.
1060            Post_call is the old Call node and collects the results of the called
1061            graph. Both will end up being a tuple.  -- */
1062         post_bl = get_nodes_block(call);
1063         set_irg_current_block(current_ir_graph, post_bl);
1064         /* XxMxPxPxPxT of Start + parameter of Call */
1065         in[pn_Start_X_initial_exec]   = new_Jmp();
1066         in[pn_Start_M]                = get_Call_mem(call);
1067         in[pn_Start_P_frame_base]     = get_irg_frame(current_ir_graph);
1068         in[pn_Start_P_globals]        = get_irg_globals(current_ir_graph);
1069         in[pn_Start_P_tls]            = get_irg_tls(current_ir_graph);
1070         in[pn_Start_T_args]           = new_Tuple(get_Call_n_params(call), get_Call_param_arr(call));
1071         /* in[pn_Start_P_value_arg_base] = ??? */
1072         assert(pn_Start_P_value_arg_base == pn_Start_max - 1 && "pn_Start_P_value_arg_base not supported, fix");
1073         pre_call = new_Tuple(pn_Start_max - 1, in);
1074         post_call = call;
1075
1076         /* --
1077            The new block gets the ins of the old block, pre_call and all its
1078            predecessors and all Phi nodes. -- */
1079         part_block(pre_call);
1080
1081         /* -- Prepare state for dead node elimination -- */
1082         /* Visited flags in calling irg must be >= flag in called irg.
1083            Else walker and arity computation will not work. */
1084         if (get_irg_visited(current_ir_graph) <= get_irg_visited(called_graph))
1085                 set_irg_visited(current_ir_graph, get_irg_visited(called_graph)+1);
1086         if (get_irg_block_visited(current_ir_graph)< get_irg_block_visited(called_graph))
1087                 set_irg_block_visited(current_ir_graph, get_irg_block_visited(called_graph));
1088         /* Set pre_call as new Start node in link field of the start node of
1089            calling graph and pre_calls block as new block for the start block
1090            of calling graph.
1091            Further mark these nodes so that they are not visited by the
1092            copying. */
1093         set_irn_link(get_irg_start(called_graph), pre_call);
1094         set_irn_visited(get_irg_start(called_graph), get_irg_visited(current_ir_graph));
1095         set_irn_link(get_irg_start_block(called_graph), get_nodes_block(pre_call));
1096         set_irn_visited(get_irg_start_block(called_graph), get_irg_visited(current_ir_graph));
1097         set_irn_link(get_irg_bad(called_graph), get_irg_bad(current_ir_graph));
1098         set_irn_visited(get_irg_bad(called_graph), get_irg_visited(current_ir_graph));
1099
1100         /* Initialize for compaction of in arrays */
1101         inc_irg_block_visited(current_ir_graph);
1102
1103         /* -- Replicate local entities of the called_graph -- */
1104         /* copy the entities. */
1105         called_frame = get_irg_frame_type(called_graph);
1106         for (i = 0; i < get_class_n_members(called_frame); i++) {
1107                 ir_entity *new_ent, *old_ent;
1108                 old_ent = get_class_member(called_frame, i);
1109                 new_ent = copy_entity_own(old_ent, get_cur_frame_type());
1110                 set_entity_link(old_ent, new_ent);
1111         }
1112
1113         /* visited is > than that of called graph.  With this trick visited will
1114            remain unchanged so that an outer walker, e.g., searching the call nodes
1115             to inline, calling this inline will not visit the inlined nodes. */
1116         set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
1117
1118         /* -- Performing dead node elimination inlines the graph -- */
1119         /* Copies the nodes to the obstack of current_ir_graph. Updates links to new
1120            entities. */
1121         irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds,
1122                  get_irg_frame_type(called_graph));
1123
1124         /* Repair called_graph */
1125         set_irg_visited(called_graph, get_irg_visited(current_ir_graph));
1126         set_irg_block_visited(called_graph, get_irg_block_visited(current_ir_graph));
1127         set_Block_block_visited(get_irg_start_block(called_graph), 0);
1128
1129         /* -- Merge the end of the inlined procedure with the call site -- */
1130         /* We will turn the old Call node into a Tuple with the following
1131            predecessors:
1132            -1:  Block of Tuple.
1133            0: Phi of all Memories of Return statements.
1134            1: Jmp from new Block that merges the control flow from all exception
1135            predecessors of the old end block.
1136            2: Tuple of all arguments.
1137            3: Phi of Exception memories.
1138            In case the old Call directly branches to End on an exception we don't
1139            need the block merging all exceptions nor the Phi of the exception
1140            memories.
1141         */
1142
1143         /* -- Precompute some values -- */
1144         end_bl = get_new_node(get_irg_end_block(called_graph));
1145         end = get_new_node(get_irg_end(called_graph));
1146         arity = get_irn_arity(end_bl);    /* arity = n_exc + n_ret  */
1147         n_res = get_method_n_ress(get_Call_type(call));
1148
1149         res_pred = xmalloc(n_res * sizeof(*res_pred));
1150         cf_pred  = xmalloc(arity * sizeof(*res_pred));
1151
1152         set_irg_current_block(current_ir_graph, post_bl); /* just to make sure */
1153
1154         /* -- archive keepalives -- */
1155         irn_arity = get_irn_arity(end);
1156         for (i = 0; i < irn_arity; i++) {
1157                 ir_node *ka = get_End_keepalive(end, i);
1158                 if (! is_Bad(ka))
1159                         add_End_keepalive(get_irg_end(current_ir_graph), ka);
1160         }
1161
1162         /* The new end node will die.  We need not free as the in array is on the obstack:
1163            copy_node() only generated 'D' arrays. */
1164
1165         /* -- Replace Return nodes by Jump nodes. -- */
1166         n_ret = 0;
1167         for (i = 0; i < arity; i++) {
1168                 ir_node *ret;
1169                 ret = get_irn_n(end_bl, i);
1170                 if (is_Return(ret)) {
1171                         cf_pred[n_ret] = new_r_Jmp(current_ir_graph, get_nodes_block(ret));
1172                         n_ret++;
1173                 }
1174         }
1175         set_irn_in(post_bl, n_ret, cf_pred);
1176
1177         /* -- Build a Tuple for all results of the method.
1178            Add Phi node if there was more than one Return.  -- */
1179         turn_into_tuple(post_call, pn_Call_max);
1180         /* First the Memory-Phi */
1181         n_ret = 0;
1182         for (i = 0; i < arity; i++) {
1183                 ret = get_irn_n(end_bl, i);
1184                 if (is_Return(ret)) {
1185                         cf_pred[n_ret] = get_Return_mem(ret);
1186                         n_ret++;
1187                 }
1188         }
1189         phi = new_Phi(n_ret, cf_pred, mode_M);
1190         set_Tuple_pred(call, pn_Call_M_regular, phi);
1191         /* Conserve Phi-list for further inlinings -- but might be optimized */
1192         if (get_nodes_block(phi) == post_bl) {
1193                 set_irn_link(phi, get_irn_link(post_bl));
1194                 set_irn_link(post_bl, phi);
1195         }
1196         /* Now the real results */
1197         if (n_res > 0) {
1198                 for (j = 0; j < n_res; j++) {
1199                         n_ret = 0;
1200                         for (i = 0; i < arity; i++) {
1201                                 ret = get_irn_n(end_bl, i);
1202                                 if (get_irn_op(ret) == op_Return) {
1203                                         cf_pred[n_ret] = get_Return_res(ret, j);
1204                                         n_ret++;
1205                                 }
1206                         }
1207                         if (n_ret > 0)
1208                                 phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0]));
1209                         else
1210                                 phi = new_Bad();
1211                         res_pred[j] = phi;
1212                         /* Conserve Phi-list for further inlinings -- but might be optimized */
1213                         if (get_nodes_block(phi) == post_bl) {
1214                                 set_irn_link(phi, get_irn_link(post_bl));
1215                                 set_irn_link(post_bl, phi);
1216                         }
1217                 }
1218                 set_Tuple_pred(call, pn_Call_T_result, new_Tuple(n_res, res_pred));
1219         } else {
1220                 set_Tuple_pred(call, pn_Call_T_result, new_Bad());
1221         }
1222         /* handle the regular call */
1223         set_Tuple_pred(call, pn_Call_X_regular, new_Jmp());
1224
1225         /* For now, we cannot inline calls with value_base */
1226         set_Tuple_pred(call, pn_Call_P_value_res_base, new_Bad());
1227
1228         /* Finally the exception control flow.
1229            We have two (three) possible situations:
1230            First if the Call branches to an exception handler: We need to add a Phi node to
1231            collect the memory containing the exception objects.  Further we need
1232            to add another block to get a correct representation of this Phi.  To
1233            this block we add a Jmp that resolves into the X output of the Call
1234            when the Call is turned into a tuple.
1235            Second the Call branches to End, the exception is not handled.  Just
1236            add all inlined exception branches to the End node.
1237            Third: there is no Exception edge at all. Handle as case two. */
1238         if (exc_handling == exc_handler) {
1239                 n_exc = 0;
1240                 for (i = 0; i < arity; i++) {
1241                         ir_node *ret, *irn;
1242                         ret = get_irn_n(end_bl, i);
1243                         irn = skip_Proj(ret);
1244                         if (is_fragile_op(irn) || is_Raise(irn)) {
1245                                 cf_pred[n_exc] = ret;
1246                                 ++n_exc;
1247                         }
1248                 }
1249                 if (n_exc > 0) {
1250                         new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
1251                         set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
1252                         /* The Phi for the memories with the exception objects */
1253                         n_exc = 0;
1254                         for (i = 0; i < arity; i++) {
1255                                 ir_node *ret;
1256                                 ret = skip_Proj(get_irn_n(end_bl, i));
1257                                 if (is_Call(ret)) {
1258                                         cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 3);
1259                                         n_exc++;
1260                                 } else if (is_fragile_op(ret)) {
1261                                         /* We rely that all cfops have the memory output at the same position. */
1262                                         cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 0);
1263                                         n_exc++;
1264                                 } else if (get_irn_op(ret) == op_Raise) {
1265                                         cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 1);
1266                                         n_exc++;
1267                                 }
1268                         }
1269                         set_Tuple_pred(call, pn_Call_M_except, new_Phi(n_exc, cf_pred, mode_M));
1270                 } else {
1271                         set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1272                         set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1273                 }
1274         } else {
1275                 ir_node *main_end_bl;
1276                 int main_end_bl_arity;
1277                 ir_node **end_preds;
1278
1279                 /* assert(exc_handling == 1 || no exceptions. ) */
1280                 n_exc = 0;
1281                 for (i = 0; i < arity; i++) {
1282                         ir_node *ret = get_irn_n(end_bl, i);
1283                         ir_node *irn = skip_Proj(ret);
1284
1285                         if (is_fragile_op(irn) || (get_irn_op(irn) == op_Raise)) {
1286                                 cf_pred[n_exc] = ret;
1287                                 n_exc++;
1288                         }
1289                 }
1290                 main_end_bl = get_irg_end_block(current_ir_graph);
1291                 main_end_bl_arity = get_irn_arity(main_end_bl);
1292                 end_preds =  xmalloc((n_exc + main_end_bl_arity) * sizeof(*end_preds));
1293
1294                 for (i = 0; i < main_end_bl_arity; ++i)
1295                         end_preds[i] = get_irn_n(main_end_bl, i);
1296                 for (i = 0; i < n_exc; ++i)
1297                         end_preds[main_end_bl_arity + i] = cf_pred[i];
1298                 set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
1299                 set_Tuple_pred(call, pn_Call_X_except,  new_Bad());
1300                 set_Tuple_pred(call, pn_Call_M_except,  new_Bad());
1301                 free(end_preds);
1302         }
1303         free(res_pred);
1304         free(cf_pred);
1305
1306         /* --  Turn CSE back on. -- */
1307         set_optimize(rem_opt);
1308
1309         return 1;
1310 }
1311
1312 /********************************************************************/
1313 /* Apply inlineing to small methods.                                */
1314 /********************************************************************/
1315
1316 /** Represents a possible inlinable call in a graph. */
1317 typedef struct _call_entry call_entry;
1318 struct _call_entry {
1319         ir_node    *call;   /**< the Call */
1320         ir_graph   *callee; /**< the callee called here */
1321         call_entry *next;   /**< for linking the next one */
1322 };
1323
1324 /**
1325  * environment for inlining small irgs
1326  */
1327 typedef struct _inline_env_t {
1328         struct obstack obst;  /**< an obstack where call_entries are allocated on. */
1329         call_entry *head;     /**< the head of the call entry list */
1330         call_entry *tail;     /**< the tail of the call entry list */
1331 } inline_env_t;
1332
1333 /**
1334  * Returns the irg called from a Call node. If the irg is not
1335  * known, NULL is returned.
1336  */
1337 static ir_graph *get_call_called_irg(ir_node *call) {
1338         ir_node *addr;
1339         ir_graph *called_irg = NULL;
1340
1341         addr = get_Call_ptr(call);
1342         if (is_SymConst(addr) && get_SymConst_kind(addr) == symconst_addr_ent) {
1343                 called_irg = get_entity_irg(get_SymConst_entity(addr));
1344         }
1345
1346         return called_irg;
1347 }
1348
1349 /**
1350  * Walker: Collect all calls to known graphs inside a graph.
1351  */
1352 static void collect_calls(ir_node *call, void *env) {
1353         if (is_Call(call)) {
1354                 ir_graph *called_irg = get_call_called_irg(call);
1355                 if (called_irg) {
1356                         /* The Call node calls a locally defined method.  Remember to inline. */
1357                         inline_env_t *ienv  = env;
1358                         call_entry   *entry = obstack_alloc(&ienv->obst, sizeof(*entry));
1359                         entry->call   = call;
1360                         entry->callee = called_irg;
1361                         entry->next   = NULL;
1362
1363                         if (ienv->tail == NULL)
1364                                 ienv->head = entry;
1365                         else
1366                                 ienv->tail->next = entry;
1367                         ienv->tail = entry;
1368                 }
1369         }
1370 }
1371
1372 /**
1373  * Inlines all small methods at call sites where the called address comes
1374  * from a Const node that references the entity representing the called
1375  * method.
1376  * The size argument is a rough measure for the code size of the method:
1377  * Methods where the obstack containing the firm graph is smaller than
1378  * size are inlined.
1379  */
1380 void inline_small_irgs(ir_graph *irg, int size) {
1381   ir_graph *rem = current_ir_graph;
1382         inline_env_t env;
1383         call_entry *entry;
1384         DEBUG_ONLY(firm_dbg_module_t *dbg;)
1385
1386         if (!(get_opt_optimize() && get_opt_inline())) return;
1387
1388         FIRM_DBG_REGISTER(dbg, "firm.opt.inline");
1389
1390         current_ir_graph = irg;
1391         /* Handle graph state */
1392         assert(get_irg_phase_state(irg) != phase_building);
1393         free_callee_info(irg);
1394
1395         /* Find Call nodes to inline.
1396            (We can not inline during a walk of the graph, as inlineing the same
1397            method several times changes the visited flag of the walked graph:
1398            after the first inlineing visited of the callee equals visited of
1399            the caller.  With the next inlineing both are increased.) */
1400         obstack_init(&env.obst);
1401         env.head = env.tail = NULL;
1402         irg_walk_graph(irg, NULL, collect_calls, &env);
1403
1404         if (env.head != NULL) {
1405                 /* There are calls to inline */
1406                 collect_phiprojs(irg);
1407                 for (entry = env.head; entry != NULL; entry = entry->next) {
1408                         ir_graph *callee = entry->callee;
1409                         if (((_obstack_memory_used(callee->obst) - (int)obstack_room(callee->obst)) < size) ||
1410                             (get_irg_inline_property(callee) >= irg_inline_forced)) {
1411                                 inline_method(entry->call, callee);
1412                         }
1413                 }
1414         }
1415         obstack_free(&env.obst, NULL);
1416         current_ir_graph = rem;
1417 }
1418
1419 /**
1420  * Environment for inlining irgs.
1421  */
1422 typedef struct {
1423   int n_nodes;             /**< Number of nodes in graph except Id, Tuple, Proj, Start, End. */
1424         int n_nodes_orig;        /**< for statistics */
1425         call_entry *call_head;   /**< The head of the list of all call nodes in this graph. */
1426         call_entry *call_tail;   /**< The tail of the list of all call nodes in this graph .*/
1427         int n_call_nodes;        /**< Number of Call nodes in the graph. */
1428         int n_call_nodes_orig;   /**< for statistics */
1429         int n_callers;           /**< Number of known graphs that call this graphs. */
1430         int n_callers_orig;      /**< for statistics */
1431         int got_inline;          /**< Set, if at leat one call inside this graph was inlined. */
1432 } inline_irg_env;
1433
1434 /**
1435  * Allocate a new environment for inlining.
1436  */
1437 static inline_irg_env *alloc_inline_irg_env(struct obstack *obst) {
1438         inline_irg_env *env    = obstack_alloc(obst, sizeof(*env));
1439         env->n_nodes           = -2; /* do not count count Start, End */
1440         env->n_nodes_orig      = -2; /* do not count Start, End */
1441         env->call_head         = NULL;
1442         env->call_tail         = NULL;
1443         env->n_call_nodes      = 0;
1444         env->n_call_nodes_orig = 0;
1445         env->n_callers         = 0;
1446         env->n_callers_orig    = 0;
1447         env->got_inline        = 0;
1448         return env;
1449 }
1450
1451 typedef struct walker_env {
1452         struct obstack *obst; /**< the obstack for allocations. */
1453         inline_irg_env *x;    /**< the inline environment */
1454         int ignore_runtime;   /**< the ignore runtime flag */
1455 } wenv_t;
1456
1457 /**
1458  * post-walker: collect all calls in the inline-environment
1459  * of a graph and sum some statistics.
1460  */
1461 static void collect_calls2(ir_node *call, void *ctx) {
1462         wenv_t         *env = ctx;
1463         inline_irg_env *x = env->x;
1464         ir_op          *op = get_irn_op(call);
1465         ir_graph       *callee;
1466         call_entry     *entry;
1467
1468         /* count meaningful nodes in irg */
1469         if (op != op_Proj && op != op_Tuple && op != op_Sync) {
1470                 ++x->n_nodes;
1471                 ++x->n_nodes_orig;
1472         }
1473
1474         if (op != op_Call) return;
1475
1476         /* check, if it's a runtime call */
1477         if (env->ignore_runtime) {
1478                 ir_node *symc = get_Call_ptr(call);
1479
1480                 if (is_SymConst(symc) && get_SymConst_kind(symc) == symconst_addr_ent) {
1481                         ir_entity *ent = get_SymConst_entity(symc);
1482
1483                         if (get_entity_additional_properties(ent) & mtp_property_runtime)
1484                                 return;
1485                 }
1486         }
1487
1488         /* collect all call nodes */
1489         ++x->n_call_nodes;
1490         ++x->n_call_nodes_orig;
1491
1492         callee = get_call_called_irg(call);
1493         if (callee) {
1494                 inline_irg_env *callee_env = get_irg_link(callee);
1495                 /* count all static callers */
1496                 ++callee_env->n_callers;
1497                 ++callee_env->n_callers_orig;
1498
1499                 /* link it in the list of possible inlinable entries */
1500                 entry = obstack_alloc(env->obst, sizeof(*entry));
1501                 entry->call   = call;
1502                 entry->callee = callee;
1503                 entry->next   = NULL;
1504                 if (x->call_tail == NULL)
1505                         x->call_head = entry;
1506                 else
1507                         x->call_tail->next = entry;
1508                 x->call_tail = entry;
1509         }
1510 }
1511
1512 /**
1513  * Returns TRUE if the number of callers in 0 in the irg's environment,
1514  * hence this irg is a leave.
1515  */
1516 INLINE static int is_leave(ir_graph *irg) {
1517         inline_irg_env *env = get_irg_link(irg);
1518         return env->n_call_nodes == 0;
1519 }
1520
1521 /**
1522  * Returns TRUE if the number of callers is smaller size in the irg's environment.
1523  */
1524 INLINE static int is_smaller(ir_graph *callee, int size) {
1525         inline_irg_env *env = get_irg_link(callee);
1526         return env->n_nodes < size;
1527 }
1528
1529 /**
1530  * Append the nodes of the list src to the nodes of the list in environment dst.
1531  */
1532 static void append_call_list(struct obstack *obst, inline_irg_env *dst, call_entry *src) {
1533         call_entry *entry, *nentry;
1534
1535         /* Note that the src list points to Call nodes in the inlined graph, but
1536            we need Call nodes in our graph. Luckily the inliner leaves this information
1537            in the link field. */
1538         for (entry = src; entry != NULL; entry = entry->next) {
1539                 nentry = obstack_alloc(obst, sizeof(*nentry));
1540                 nentry->call   = get_irn_link(entry->call);
1541                 nentry->callee = entry->callee;
1542                 nentry->next   = NULL;
1543                 dst->call_tail->next = nentry;
1544                 dst->call_tail       = nentry;
1545         }
1546 }
1547
1548 /*
1549  * Inlines small leave methods at call sites where the called address comes
1550  * from a Const node that references the entity representing the called
1551  * method.
1552  * The size argument is a rough measure for the code size of the method:
1553  * Methods where the obstack containing the firm graph is smaller than
1554  * size are inlined.
1555  */
1556 void inline_leave_functions(int maxsize, int leavesize, int size, int ignore_runtime) {
1557         inline_irg_env   *env;
1558         ir_graph         *irg;
1559         int              i, n_irgs;
1560         ir_graph         *rem;
1561         int              did_inline;
1562         wenv_t           wenv;
1563         call_entry       *entry, *tail;
1564         const call_entry *centry;
1565         struct obstack   obst;
1566         DEBUG_ONLY(firm_dbg_module_t *dbg;)
1567
1568         if (!(get_opt_optimize() && get_opt_inline())) return;
1569
1570         FIRM_DBG_REGISTER(dbg, "firm.opt.inline");
1571         rem = current_ir_graph;
1572         obstack_init(&obst);
1573
1574         /* extend all irgs by a temporary data structure for inlining. */
1575         n_irgs = get_irp_n_irgs();
1576         for (i = 0; i < n_irgs; ++i)
1577                 set_irg_link(get_irp_irg(i), alloc_inline_irg_env(&obst));
1578
1579         /* Precompute information in temporary data structure. */
1580         wenv.obst           = &obst;
1581         wenv.ignore_runtime = ignore_runtime;
1582         for (i = 0; i < n_irgs; ++i) {
1583                 ir_graph *irg = get_irp_irg(i);
1584
1585                 assert(get_irg_phase_state(irg) != phase_building);
1586                 free_callee_info(irg);
1587
1588                 wenv.x = get_irg_link(irg);
1589                 irg_walk_graph(irg, NULL, collect_calls2, &wenv);
1590         }
1591
1592         /* -- and now inline. -- */
1593
1594         /* Inline leaves recursively -- we might construct new leaves. */
1595         do {
1596                 did_inline = 0;
1597
1598                 for (i = 0; i < n_irgs; ++i) {
1599                         ir_node *call;
1600                         int phiproj_computed = 0;
1601
1602                         current_ir_graph = get_irp_irg(i);
1603                         env = (inline_irg_env *)get_irg_link(current_ir_graph);
1604
1605                         tail = NULL;
1606                         for (entry = env->call_head; entry != NULL; entry = entry->next) {
1607                                 ir_graph *callee;
1608
1609                                 if (env->n_nodes > maxsize) break;
1610
1611                                 call   = entry->call;
1612                                 callee = entry->callee;
1613
1614                                 if (is_leave(callee) && is_smaller(callee, leavesize)) {
1615                                         if (!phiproj_computed) {
1616                                                 phiproj_computed = 1;
1617                                                 collect_phiprojs(current_ir_graph);
1618                                         }
1619                                         did_inline = inline_method(call, callee);
1620
1621                                         if (did_inline) {
1622                                                 /* Do some statistics */
1623                                                 inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1624
1625                                                 env->got_inline = 1;
1626                                                 --env->n_call_nodes;
1627                                                 env->n_nodes += callee_env->n_nodes;
1628                                                 --callee_env->n_callers;
1629
1630                                                 /* remove this call from the list */
1631                                                 if (tail != NULL)
1632                                                         tail->next = entry->next;
1633                                                 else
1634                                                         env->call_head = entry->next;
1635                                                 continue;
1636                                         }
1637                                 }
1638                                 tail = entry;
1639                         }
1640                         env->call_tail = tail;
1641                 }
1642         } while (did_inline);
1643
1644         /* inline other small functions. */
1645         for (i = 0; i < n_irgs; ++i) {
1646                 ir_node *call;
1647                 int phiproj_computed = 0;
1648
1649                 current_ir_graph = get_irp_irg(i);
1650                 env = (inline_irg_env *)get_irg_link(current_ir_graph);
1651
1652                 /* note that the list of possible calls is updated during the process */
1653                 tail = NULL;
1654                 for (entry = env->call_head; entry != NULL; entry = entry->next) {
1655                         ir_graph *callee;
1656
1657                         call   = entry->call;
1658                         callee = entry->callee;
1659
1660                         if (((is_smaller(callee, size) && (env->n_nodes < maxsize)) ||    /* small function */
1661                                 (get_irg_inline_property(callee) >= irg_inline_forced))) {
1662                                 if (!phiproj_computed) {
1663                                         phiproj_computed = 1;
1664                                         collect_phiprojs(current_ir_graph);
1665                                 }
1666                                 if (inline_method(call, callee)) {
1667                                         inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1668
1669                                         /* callee was inline. Append it's call list. */
1670                                         env->got_inline = 1;
1671                                         --env->n_call_nodes;
1672                                         append_call_list(&obst, env, callee_env->call_head);
1673                                         env->n_call_nodes += callee_env->n_call_nodes;
1674                                         env->n_nodes += callee_env->n_nodes;
1675                                         --callee_env->n_callers;
1676
1677                                         /* after we have inlined callee, all called methods inside callee
1678                                            are now called once more */
1679                                         for (centry = callee_env->call_head; centry != NULL; centry = centry->next) {
1680                                                 inline_irg_env *penv = get_irg_link(centry->callee);
1681                                                 ++penv->n_callers;
1682                                         }
1683
1684                                         /* remove this call from the list */
1685                                         if (tail != NULL)
1686                                                 tail->next = entry->next;
1687                                         else
1688                                                 env->call_head = entry->next;
1689                                         continue;
1690                                 }
1691                         }
1692                         tail = entry;
1693                 }
1694                 env->call_tail = tail;
1695         }
1696
1697         for (i = 0; i < n_irgs; ++i) {
1698                 irg = get_irp_irg(i);
1699                 env = (inline_irg_env *)get_irg_link(irg);
1700
1701                 if (env->got_inline) {
1702                         /* this irg got calls inlined */
1703                         set_irg_outs_inconsistent(irg);
1704                         set_irg_doms_inconsistent(irg);
1705
1706                         optimize_graph_df(irg);
1707                         optimize_cf(irg);
1708                 }
1709                 if (env->got_inline || (env->n_callers_orig != env->n_callers))
1710                         DB((dbg, SET_LEVEL_1, "Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
1711                         env->n_nodes_orig, env->n_nodes, env->n_call_nodes_orig, env->n_call_nodes,
1712                         env->n_callers_orig, env->n_callers,
1713                         get_entity_name(get_irg_entity(irg))));
1714         }
1715
1716         obstack_free(&obst, NULL);
1717         current_ir_graph = rem;
1718 }
1719
1720 /*******************************************************************/
1721 /*  Code Placement.  Pins all floating nodes to a block where they */
1722 /*  will be executed only if needed.                               */
1723 /*******************************************************************/
1724
1725 /**
1726  * Returns non-zero, is a block is not reachable from Start.
1727  *
1728  * @param block  the block to test
1729  */
1730 static int
1731 is_Block_unreachable(ir_node *block) {
1732         return is_Block_dead(block) || get_Block_dom_depth(block) < 0;
1733 }
1734
1735 /**
1736  * Find the earliest correct block for node n.  --- Place n into the
1737  * same Block as its dominance-deepest Input.
1738  *
1739  * We have to avoid calls to get_nodes_block() here
1740  * because the graph is floating.
1741  *
1742  * move_out_of_loops() expects that place_floats_early() have placed
1743  * all "living" nodes into a living block. That's why we must
1744  * move nodes in dead block with "live" successors into a valid
1745  * block.
1746  * We move them just into the same block as it's successor (or
1747  * in case of a Phi into the effective use block). For Phi successors,
1748  * this may still be a dead block, but then there is no real use, as
1749  * the control flow will be dead later.
1750  *
1751  * @param n         the node to be placed
1752  * @param worklist  a worklist, predecessors of non-floating nodes are placed here
1753  */
1754 static void
1755 place_floats_early(ir_node *n, waitq *worklist) {
1756         int i, irn_arity;
1757
1758         /* we must not run into an infinite loop */
1759         assert(irn_not_visited(n));
1760         mark_irn_visited(n);
1761
1762         /* Place floating nodes. */
1763         if (get_irn_pinned(n) == op_pin_state_floats) {
1764                 ir_node *curr_block = get_irn_n(n, -1);
1765                 int in_dead_block   = is_Block_unreachable(curr_block);
1766                 int depth           = 0;
1767                 ir_node *b          = NULL;   /* The block to place this node in */
1768
1769                 assert(is_no_Block(n));
1770
1771                 if (is_irn_start_block_placed(n)) {
1772                         /* These nodes will not be placed by the loop below. */
1773                         b = get_irg_start_block(current_ir_graph);
1774                         depth = 1;
1775                 }
1776
1777                 /* find the block for this node. */
1778                 irn_arity = get_irn_arity(n);
1779                 for (i = 0; i < irn_arity; i++) {
1780                         ir_node *pred = get_irn_n(n, i);
1781                         ir_node *pred_block;
1782
1783                         if ((irn_not_visited(pred))
1784                             && (get_irn_pinned(pred) == op_pin_state_floats)) {
1785
1786                                 /*
1787                                  * If the current node is NOT in a dead block, but one of its
1788                                  * predecessors is, we must move the predecessor to a live block.
1789                                  * Such thing can happen, if global CSE chose a node from a dead block.
1790                                  * We move it simply to our block.
1791                                  * Note that neither Phi nor End nodes are floating, so we don't
1792                                  * need to handle them here.
1793                                  */
1794                                 if (! in_dead_block) {
1795                                         if (get_irn_pinned(pred) == op_pin_state_floats &&
1796                                                 is_Block_unreachable(get_irn_n(pred, -1)))
1797                                                 set_nodes_block(pred, curr_block);
1798                                 }
1799                                 place_floats_early(pred, worklist);
1800                         }
1801
1802                         /*
1803                          * A node in the Bad block must stay in the bad block,
1804                          * so don't compute a new block for it.
1805                          */
1806                         if (in_dead_block)
1807                                 continue;
1808
1809                         /* Because all loops contain at least one op_pin_state_pinned node, now all
1810                            our inputs are either op_pin_state_pinned or place_early() has already
1811                            been finished on them.  We do not have any unfinished inputs!  */
1812                         pred_block = get_irn_n(pred, -1);
1813                         if ((!is_Block_dead(pred_block)) &&
1814                                 (get_Block_dom_depth(pred_block) > depth)) {
1815                                 b = pred_block;
1816                                 depth = get_Block_dom_depth(pred_block);
1817                         }
1818                         /* Avoid that the node is placed in the Start block */
1819                         if ((depth == 1) && (get_Block_dom_depth(get_irn_n(n, -1)) > 1)
1820                                 && get_irg_phase_state(current_ir_graph) != phase_backend) {
1821                                 b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
1822                                 assert(b != get_irg_start_block(current_ir_graph));
1823                                 depth = 2;
1824                         }
1825                 }
1826                 if (b)
1827                         set_nodes_block(n, b);
1828         }
1829
1830         /*
1831          * Add predecessors of non floating nodes and non-floating predecessors
1832          * of floating nodes to worklist and fix their blocks if the are in dead block.
1833          */
1834         irn_arity = get_irn_arity(n);
1835
1836         if (get_irn_op(n) == op_End) {
1837                 /*
1838                  * Simplest case: End node. Predecessors are keep-alives,
1839                  * no need to move out of dead block.
1840                  */
1841                 for (i = -1; i < irn_arity; ++i) {
1842                         ir_node *pred = get_irn_n(n, i);
1843                         if (irn_not_visited(pred))
1844                                 waitq_put(worklist, pred);
1845                 }
1846         } else if (is_Block(n)) {
1847                 /*
1848                  * Blocks: Predecessors are control flow, no need to move
1849                  * them out of dead block.
1850                  */
1851                 for (i = irn_arity - 1; i >= 0; --i) {
1852                         ir_node *pred = get_irn_n(n, i);
1853                         if (irn_not_visited(pred))
1854                                 waitq_put(worklist, pred);
1855                 }
1856         } else if (is_Phi(n)) {
1857                 ir_node *pred;
1858                 ir_node *curr_block = get_irn_n(n, -1);
1859                 int in_dead_block   = is_Block_unreachable(curr_block);
1860
1861                 /*
1862                  * Phi nodes: move nodes from dead blocks into the effective use
1863                  * of the Phi-input if the Phi is not in a bad block.
1864                  */
1865                 pred = get_irn_n(n, -1);
1866                 if (irn_not_visited(pred))
1867                         waitq_put(worklist, pred);
1868
1869                 for (i = irn_arity - 1; i >= 0; --i) {
1870                         ir_node *pred = get_irn_n(n, i);
1871
1872                         if (irn_not_visited(pred)) {
1873                                 if (! in_dead_block &&
1874                                         get_irn_pinned(pred) == op_pin_state_floats &&
1875                                         is_Block_unreachable(get_irn_n(pred, -1))) {
1876                                         set_nodes_block(pred, get_Block_cfgpred_block(curr_block, i));
1877                                 }
1878                                 waitq_put(worklist, pred);
1879                         }
1880                 }
1881         } else {
1882                 ir_node *pred;
1883                 ir_node *curr_block = get_irn_n(n, -1);
1884                 int in_dead_block   = is_Block_unreachable(curr_block);
1885
1886                 /*
1887                  * All other nodes: move nodes from dead blocks into the same block.
1888                  */
1889                 pred = get_irn_n(n, -1);
1890                 if (irn_not_visited(pred))
1891                         waitq_put(worklist, pred);
1892
1893                 for (i = irn_arity - 1; i >= 0; --i) {
1894                         ir_node *pred = get_irn_n(n, i);
1895
1896                         if (irn_not_visited(pred)) {
1897                                 if (! in_dead_block &&
1898                                         get_irn_pinned(pred) == op_pin_state_floats &&
1899                                         is_Block_unreachable(get_irn_n(pred, -1))) {
1900                                         set_nodes_block(pred, curr_block);
1901                                 }
1902                                 waitq_put(worklist, pred);
1903                         }
1904                 }
1905         }
1906 }
1907
1908 /**
1909  * Floating nodes form subgraphs that begin at nodes as Const, Load,
1910  * Start, Call and that end at op_pin_state_pinned nodes as Store, Call.  Place_early
1911  * places all floating nodes reachable from its argument through floating
1912  * nodes and adds all beginnings at op_pin_state_pinned nodes to the worklist.
1913  *
1914  * @param worklist   a worklist, used for the algorithm, empty on in/output
1915  */
1916 static void place_early(waitq *worklist) {
1917         assert(worklist);
1918         inc_irg_visited(current_ir_graph);
1919
1920         /* this inits the worklist */
1921         place_floats_early(get_irg_end(current_ir_graph), worklist);
1922
1923         /* Work the content of the worklist. */
1924         while (!waitq_empty(worklist)) {
1925                 ir_node *n = waitq_get(worklist);
1926                 if (irn_not_visited(n))
1927                         place_floats_early(n, worklist);
1928         }
1929
1930         set_irg_outs_inconsistent(current_ir_graph);
1931         set_irg_pinned(current_ir_graph, op_pin_state_pinned);
1932 }
1933
1934 /**
1935  * Compute the deepest common ancestor of block and dca.
1936  */
1937 static ir_node *calc_dca(ir_node *dca, ir_node *block) {
1938         assert(block);
1939
1940         /* we do not want to place nodes in dead blocks */
1941         if (is_Block_dead(block))
1942                 return dca;
1943
1944         /* We found a first legal placement. */
1945         if (!dca) return block;
1946
1947         /* Find a placement that is dominates both, dca and block. */
1948         while (get_Block_dom_depth(block) > get_Block_dom_depth(dca))
1949                 block = get_Block_idom(block);
1950
1951         while (get_Block_dom_depth(dca) > get_Block_dom_depth(block)) {
1952                 dca = get_Block_idom(dca);
1953         }
1954
1955         while (block != dca) {
1956                 block = get_Block_idom(block); dca = get_Block_idom(dca);
1957         }
1958
1959         return dca;
1960 }
1961
1962 /** Deepest common dominance ancestor of DCA and CONSUMER of PRODUCER.
1963  * I.e., DCA is the block where we might place PRODUCER.
1964  * A data flow edge points from producer to consumer.
1965  */
1966 static ir_node *
1967 consumer_dom_dca(ir_node *dca, ir_node *consumer, ir_node *producer) {
1968         ir_node *block = NULL;
1969
1970         /* Compute the latest block into which we can place a node so that it is
1971            before consumer. */
1972         if (get_irn_op(consumer) == op_Phi) {
1973                 /* our consumer is a Phi-node, the effective use is in all those
1974                    blocks through which the Phi-node reaches producer */
1975                 int i, irn_arity;
1976                 ir_node *phi_block = get_nodes_block(consumer);
1977                 irn_arity = get_irn_arity(consumer);
1978
1979                 for (i = 0;  i < irn_arity; i++) {
1980                         if (get_irn_n(consumer, i) == producer) {
1981                                 ir_node *new_block = get_nodes_block(get_Block_cfgpred(phi_block, i));
1982
1983                                 if (! is_Block_unreachable(new_block))
1984                                         block = calc_dca(block, new_block);
1985                         }
1986                 }
1987
1988                 if (! block)
1989                         block = get_irn_n(producer, -1);
1990         } else {
1991                 assert(is_no_Block(consumer));
1992                 block = get_nodes_block(consumer);
1993         }
1994
1995         /* Compute the deepest common ancestor of block and dca. */
1996         return calc_dca(dca, block);
1997 }
1998
1999 /* FIXME: the name clashes here with the function from ana/field_temperature.c
2000  * please rename. */
2001 static INLINE int get_irn_loop_depth(ir_node *n) {
2002         return get_loop_depth(get_irn_loop(n));
2003 }
2004
2005 /**
2006  * Move n to a block with less loop depth than it's current block. The
2007  * new block must be dominated by early.
2008  *
2009  * @param n      the node that should be moved
2010  * @param early  the earliest block we can n move to
2011  */
2012 static void move_out_of_loops(ir_node *n, ir_node *early) {
2013         ir_node *best, *dca;
2014         assert(n && early);
2015
2016
2017         /* Find the region deepest in the dominator tree dominating
2018            dca with the least loop nesting depth, but still dominated
2019            by our early placement. */
2020         dca = get_nodes_block(n);
2021
2022         best = dca;
2023         while (dca != early) {
2024                 dca = get_Block_idom(dca);
2025                 if (!dca || is_Bad(dca)) break; /* may be Bad if not reachable from Start */
2026                 if (get_irn_loop_depth(dca) < get_irn_loop_depth(best)) {
2027                         best = dca;
2028                 }
2029         }
2030         if (best != get_nodes_block(n)) {
2031                 /* debug output
2032                 printf("Moving out of loop: "); DDMN(n);
2033                 printf(" Outermost block: "); DDMN(early);
2034                 printf(" Best block: "); DDMN(best);
2035                 printf(" Innermost block: "); DDMN(get_nodes_block(n));
2036                 */
2037                 set_nodes_block(n, best);
2038         }
2039 }
2040
2041 /* deepest common ancestor in the dominator tree of all nodes'
2042    blocks depending on us; our final placement has to dominate DCA. */
2043 static ir_node *get_deepest_common_ancestor(ir_node *node, ir_node *dca)
2044 {
2045         int i;
2046
2047         for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
2048                 ir_node *succ = get_irn_out(node, i);
2049                 ir_node *succ_blk;
2050
2051                 if (is_End(succ)) {
2052                         /*
2053                          * This consumer is the End node, a keep alive edge.
2054                          * This is not a real consumer, so we ignore it
2055                          */
2056                         continue;
2057                 }
2058
2059                 if(is_Proj(succ)) {
2060                         dca = get_deepest_common_ancestor(succ, dca);
2061                 } else {
2062                         /* ignore if succ is in dead code */
2063                         succ_blk = get_irn_n(succ, -1);
2064                         if (is_Block_unreachable(succ_blk))
2065                                 continue;
2066                         dca = consumer_dom_dca(dca, succ, node);
2067                 }
2068         }
2069
2070         return dca;
2071 }
2072
2073 static void set_projs_block(ir_node *node, ir_node *block)
2074 {
2075         int i;
2076
2077         for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
2078                 ir_node *succ = get_irn_out(node, i);
2079
2080                 assert(is_Proj(succ));
2081
2082                 if(get_irn_mode(succ) == mode_T) {
2083                         set_projs_block(succ, block);
2084                 }
2085                 set_nodes_block(succ, block);
2086         }
2087 }
2088
2089 /**
2090  * Find the latest legal block for N and place N into the
2091  * `optimal' Block between the latest and earliest legal block.
2092  * The `optimal' block is the dominance-deepest block of those
2093  * with the least loop-nesting-depth.  This places N out of as many
2094  * loops as possible and then makes it as control dependent as
2095  * possible.
2096  *
2097  * @param n         the node to be placed
2098  * @param worklist  a worklist, all successors of non-floating nodes are
2099  *                  placed here
2100  */
2101 static void place_floats_late(ir_node *n, pdeq *worklist) {
2102   int i;
2103         ir_node *early_blk;
2104
2105         assert(irn_not_visited(n)); /* no multiple placement */
2106
2107         mark_irn_visited(n);
2108
2109         /* no need to place block nodes, control nodes are already placed. */
2110         if ((get_irn_op(n) != op_Block) &&
2111             (!is_cfop(n)) &&
2112             (get_irn_mode(n) != mode_X)) {
2113                 /* Remember the early_blk placement of this block to move it
2114                    out of loop no further than the early_blk placement. */
2115                 early_blk = get_irn_n(n, -1);
2116
2117                 /*
2118                  * BEWARE: Here we also get code, that is live, but
2119                  * was in a dead block.  If the node is life, but because
2120                  * of CSE in a dead block, we still might need it.
2121                  */
2122
2123                 /* Assure that our users are all placed, except the Phi-nodes.
2124                 --- Each data flow cycle contains at least one Phi-node.  We
2125                     have to break the `user has to be placed before the
2126                     producer' dependence cycle and the Phi-nodes are the
2127                     place to do so, because we need to base our placement on the
2128                     final region of our users, which is OK with Phi-nodes, as they
2129                     are op_pin_state_pinned, and they never have to be placed after a
2130                     producer of one of their inputs in the same block anyway. */
2131                 for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
2132                         ir_node *succ = get_irn_out(n, i);
2133                         if (irn_not_visited(succ) && (get_irn_op(succ) != op_Phi))
2134                                 place_floats_late(succ, worklist);
2135                 }
2136
2137                 if (! is_Block_dead(early_blk)) {
2138                         /* do only move things that where not dead */
2139                         ir_op *op = get_irn_op(n);
2140
2141                         /* We have to determine the final block of this node... except for
2142                            constants and Projs */
2143                         if ((get_irn_pinned(n) == op_pin_state_floats) &&
2144                             (op != op_Const)    &&
2145                             (op != op_SymConst) &&
2146                             (op != op_Proj))
2147                         {
2148                                 /* deepest common ancestor in the dominator tree of all nodes'
2149                                    blocks depending on us; our final placement has to dominate
2150                                    DCA. */
2151                                 ir_node *dca = get_deepest_common_ancestor(n, NULL);
2152                                 if (dca != NULL) {
2153                                         set_nodes_block(n, dca);
2154                                         move_out_of_loops(n, early_blk);
2155                                         if(get_irn_mode(n) == mode_T) {
2156                                                 set_projs_block(n, get_nodes_block(n));
2157                                         }
2158                                 }
2159                         }
2160                 }
2161         }
2162
2163         /* Add successors of all non-floating nodes on list. (Those of floating
2164            nodes are placed already and therefore are marked.)  */
2165         for (i = 0; i < get_irn_n_outs(n); i++) {
2166                 ir_node *succ = get_irn_out(n, i);
2167                 if (irn_not_visited(get_irn_out(n, i))) {
2168                         pdeq_putr(worklist, succ);
2169                 }
2170         }
2171 }
2172
2173 /**
2174  * Place floating nodes on the given worklist as late as possible using
2175  * the dominance tree.
2176  *
2177  * @param worklist   the worklist containing the nodes to place
2178  */
2179 static void place_late(waitq *worklist) {
2180         assert(worklist);
2181         inc_irg_visited(current_ir_graph);
2182
2183         /* This fills the worklist initially. */
2184         place_floats_late(get_irg_start_block(current_ir_graph), worklist);
2185
2186         /* And now empty the worklist again... */
2187         while (!waitq_empty(worklist)) {
2188                 ir_node *n = waitq_get(worklist);
2189                 if (irn_not_visited(n))
2190                         place_floats_late(n, worklist);
2191         }
2192 }
2193
2194 /* Code Placement. */
2195 void place_code(ir_graph *irg) {
2196         waitq *worklist;
2197         ir_graph *rem = current_ir_graph;
2198
2199         current_ir_graph = irg;
2200
2201         /* Handle graph state */
2202         assert(get_irg_phase_state(irg) != phase_building);
2203         assure_doms(irg);
2204
2205         if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) {
2206                 free_loop_information(irg);
2207                 construct_backedges(irg);
2208         }
2209
2210         /* Place all floating nodes as early as possible. This guarantees
2211          a legal code placement. */
2212         worklist = new_waitq();
2213         place_early(worklist);
2214
2215         /* place_early() invalidates the outs, place_late needs them. */
2216         compute_irg_outs(irg);
2217
2218         /* Now move the nodes down in the dominator tree. This reduces the
2219            unnecessary executions of the node. */
2220         place_late(worklist);
2221
2222         set_irg_outs_inconsistent(current_ir_graph);
2223         set_irg_loopinfo_inconsistent(current_ir_graph);
2224         del_waitq(worklist);
2225         current_ir_graph = rem;
2226 }
2227
2228 typedef struct cf_env {
2229         char changed;       /**< flag indicates that the cf graphs has changed. */
2230 } cf_env;
2231
2232 /**
2233  * Called by walker of remove_critical_cf_edges().
2234  *
2235  * Place an empty block to an edge between a blocks of multiple
2236  * predecessors and a block of multiple successors.
2237  *
2238  * @param n   IR node
2239  * @param env Environment of walker.
2240  */
2241 static void walk_critical_cf_edges(ir_node *n, void *env) {
2242         int arity, i;
2243         ir_node *pre, *block, *jmp;
2244         cf_env *cenv = env;
2245         ir_graph *irg = get_irn_irg(n);
2246
2247         /* Block has multiple predecessors */
2248         arity = get_irn_arity(n);
2249         if (arity > 1) {
2250                 if (n == get_irg_end_block(irg))
2251                         return;  /*  No use to add a block here.      */
2252
2253                 for (i = 0; i < arity; ++i) {
2254                         const ir_op *cfop;
2255
2256                         pre = get_irn_n(n, i);
2257                         cfop = get_irn_op(skip_Proj(pre));
2258
2259                         if (is_op_fragile(cfop)) {
2260                                 if (cfop != op_Raise)
2261                                         goto insert;
2262                                 continue;
2263                         }
2264                         if (is_op_forking(cfop)) {
2265                                 /* Predecessor has multiple successors. Insert new control flow edge edges. */
2266 insert:
2267                                 /* set predecessor of new block */
2268                                 block = new_r_Block(irg, 1, &pre);
2269                                 /* insert new jmp node to new block */
2270                                 jmp = new_r_Jmp(irg, block);
2271                                 /* set successor of new block */
2272                                 set_irn_n(n, i, jmp);
2273                                 cenv->changed = 1;
2274                         } /* predecessor has multiple successors */
2275                 } /* for all predecessors */
2276         } /* n is a multi-entry block */
2277 }
2278
2279 void remove_critical_cf_edges(ir_graph *irg) {
2280         cf_env env;
2281
2282         env.changed = 0;
2283
2284         irg_block_walk_graph(irg, NULL, walk_critical_cf_edges, &env);
2285         if (env.changed) {
2286                 /* control flow changed */
2287                 set_irg_outs_inconsistent(irg);
2288                 set_irg_extblk_inconsistent(irg);
2289                 set_irg_doms_inconsistent(irg);
2290                 set_irg_loopinfo_inconsistent(irg);
2291         }
2292 }