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