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