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