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