fix
[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 /* Inlines a method at the given call site. */
947 int inline_method(ir_node *call, ir_graph *called_graph) {
948         ir_node *pre_call;
949         ir_node *post_call, *post_bl;
950         ir_node *in[pn_Start_max];
951         ir_node *end, *end_bl;
952         ir_node **res_pred;
953         ir_node **cf_pred;
954         ir_node *ret, *phi;
955         int arity, n_ret, n_exc, n_res, i, j, rem_opt, irn_arity;
956         int exc_handling;
957         ir_type *called_frame;
958         irg_inline_property prop = get_irg_inline_property(called_graph);
959
960         if ( (prop < irg_inline_forced) &&
961              (!get_opt_optimize() || !get_opt_inline() || (prop == irg_inline_forbidden))) return 0;
962
963         /* Do not inline variadic functions. */
964         if (get_method_variadicity(get_entity_type(get_irg_entity(called_graph))) == variadicity_variadic)
965                 return 0;
966
967         assert(get_method_n_params(get_entity_type(get_irg_entity(called_graph))) ==
968                get_method_n_params(get_Call_type(call)));
969
970         /*
971          * currently, we cannot inline two cases:
972          * - call with compound arguments
973          * - graphs that take the address of a parameter
974          */
975         if (! can_inline(call, called_graph))
976                 return 0;
977
978         /* --  Turn off optimizations, this can cause problems when allocating new nodes. -- */
979         rem_opt = get_opt_optimize();
980         set_optimize(0);
981
982         /* Handle graph state */
983         assert(get_irg_phase_state(current_ir_graph) != phase_building);
984         assert(get_irg_pinned(current_ir_graph) == op_pin_state_pinned);
985         assert(get_irg_pinned(called_graph) == op_pin_state_pinned);
986         set_irg_outs_inconsistent(current_ir_graph);
987         set_irg_extblk_inconsistent(current_ir_graph);
988         set_irg_doms_inconsistent(current_ir_graph);
989         set_irg_loopinfo_inconsistent(current_ir_graph);
990         set_irg_callee_info_state(current_ir_graph, irg_callee_info_inconsistent);
991
992         /* -- Check preconditions -- */
993         assert(is_Call(call));
994         /* @@@ does not work for InterfaceIII.java after cgana
995          assert(get_Call_type(call) == get_entity_type(get_irg_entity(called_graph)));
996          assert(smaller_type(get_entity_type(get_irg_entity(called_graph)),
997          get_Call_type(call)));
998         */
999         if (called_graph == current_ir_graph) {
1000                 set_optimize(rem_opt);
1001                 return 0;
1002         }
1003
1004         /* here we know we WILL inline, so inform the statistics */
1005         hook_inline(call, called_graph);
1006
1007         /* -- Decide how to handle exception control flow: Is there a handler
1008            for the Call node, or do we branch directly to End on an exception?
1009            exc_handling:
1010            0 There is a handler.
1011            1 Branches to End.
1012            2 Exception handling not represented in Firm. -- */
1013         {
1014                 ir_node *proj, *Mproj = NULL, *Xproj = NULL;
1015                 for (proj = get_irn_link(call); proj; proj = get_irn_link(proj)) {
1016                         assert(is_Proj(proj));
1017                         if (get_Proj_proj(proj) == pn_Call_X_except) Xproj = proj;
1018                         if (get_Proj_proj(proj) == pn_Call_M_except) Mproj = proj;
1019                 }
1020                 if      (Mproj) { assert(Xproj); exc_handling = 0; } /*  Mproj           */
1021                 else if (Xproj) {                exc_handling = 1; } /* !Mproj &&  Xproj   */
1022                 else            {                exc_handling = 2; } /* !Mproj && !Xproj   */
1023         }
1024
1025         /* --
1026            the procedure and later replaces the Start node of the called graph.
1027            Post_call is the old Call node and collects the results of the called
1028            graph. Both will end up being a tuple.  -- */
1029         post_bl = get_nodes_block(call);
1030         set_irg_current_block(current_ir_graph, post_bl);
1031         /* XxMxPxPxPxT of Start + parameter of Call */
1032         in[pn_Start_X_initial_exec]   = new_Jmp();
1033         in[pn_Start_M]                = get_Call_mem(call);
1034         in[pn_Start_P_frame_base]     = get_irg_frame(current_ir_graph);
1035         in[pn_Start_P_globals]        = get_irg_globals(current_ir_graph);
1036         in[pn_Start_P_tls]            = get_irg_tls(current_ir_graph);
1037         in[pn_Start_T_args]           = new_Tuple(get_Call_n_params(call), get_Call_param_arr(call));
1038         /* in[pn_Start_P_value_arg_base] = ??? */
1039         assert(pn_Start_P_value_arg_base == pn_Start_max - 1 && "pn_Start_P_value_arg_base not supported, fix");
1040         pre_call = new_Tuple(pn_Start_max - 1, in);
1041         post_call = call;
1042
1043         /* --
1044            The new block gets the ins of the old block, pre_call and all its
1045            predecessors and all Phi nodes. -- */
1046         part_block(pre_call);
1047
1048         /* -- Prepare state for dead node elimination -- */
1049         /* Visited flags in calling irg must be >= flag in called irg.
1050            Else walker and arity computation will not work. */
1051         if (get_irg_visited(current_ir_graph) <= get_irg_visited(called_graph))
1052                 set_irg_visited(current_ir_graph, get_irg_visited(called_graph)+1);
1053         if (get_irg_block_visited(current_ir_graph)< get_irg_block_visited(called_graph))
1054                 set_irg_block_visited(current_ir_graph, get_irg_block_visited(called_graph));
1055         /* Set pre_call as new Start node in link field of the start node of
1056            calling graph and pre_calls block as new block for the start block
1057            of calling graph.
1058            Further mark these nodes so that they are not visited by the
1059            copying. */
1060         set_irn_link(get_irg_start(called_graph), pre_call);
1061         set_irn_visited(get_irg_start(called_graph), get_irg_visited(current_ir_graph));
1062         set_irn_link(get_irg_start_block(called_graph), get_nodes_block(pre_call));
1063         set_irn_visited(get_irg_start_block(called_graph), get_irg_visited(current_ir_graph));
1064         set_irn_link(get_irg_bad(called_graph), get_irg_bad(current_ir_graph));
1065         set_irn_visited(get_irg_bad(called_graph), get_irg_visited(current_ir_graph));
1066
1067         /* Initialize for compaction of in arrays */
1068         inc_irg_block_visited(current_ir_graph);
1069
1070         /* -- Replicate local entities of the called_graph -- */
1071         /* copy the entities. */
1072         called_frame = get_irg_frame_type(called_graph);
1073         for (i = 0; i < get_class_n_members(called_frame); i++) {
1074                 ir_entity *new_ent, *old_ent;
1075                 old_ent = get_class_member(called_frame, i);
1076                 new_ent = copy_entity_own(old_ent, get_cur_frame_type());
1077                 set_entity_link(old_ent, new_ent);
1078         }
1079
1080         /* visited is > than that of called graph.  With this trick visited will
1081            remain unchanged so that an outer walker, e.g., searching the call nodes
1082             to inline, calling this inline will not visit the inlined nodes. */
1083         set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
1084
1085         /* -- Performing dead node elimination inlines the graph -- */
1086         /* Copies the nodes to the obstack of current_ir_graph. Updates links to new
1087            entities. */
1088         /* @@@ endless loops are not copied!! -- they should be, I think... */
1089         irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds,
1090                  get_irg_frame_type(called_graph));
1091
1092         /* Repair called_graph */
1093         set_irg_visited(called_graph, get_irg_visited(current_ir_graph));
1094         set_irg_block_visited(called_graph, get_irg_block_visited(current_ir_graph));
1095         set_Block_block_visited(get_irg_start_block(called_graph), 0);
1096
1097         /* -- Merge the end of the inlined procedure with the call site -- */
1098         /* We will turn the old Call node into a Tuple with the following
1099            predecessors:
1100            -1:  Block of Tuple.
1101            0: Phi of all Memories of Return statements.
1102            1: Jmp from new Block that merges the control flow from all exception
1103            predecessors of the old end block.
1104            2: Tuple of all arguments.
1105            3: Phi of Exception memories.
1106            In case the old Call directly branches to End on an exception we don't
1107            need the block merging all exceptions nor the Phi of the exception
1108            memories.
1109         */
1110
1111         /* -- Precompute some values -- */
1112         end_bl = get_new_node(get_irg_end_block(called_graph));
1113         end = get_new_node(get_irg_end(called_graph));
1114         arity = get_irn_arity(end_bl);    /* arity = n_exc + n_ret  */
1115         n_res = get_method_n_ress(get_Call_type(call));
1116
1117         res_pred = xmalloc (n_res * sizeof(*res_pred));
1118         cf_pred  = xmalloc (arity * sizeof(*res_pred));
1119
1120         set_irg_current_block(current_ir_graph, post_bl); /* just to make sure */
1121
1122         /* -- archive keepalives -- */
1123         irn_arity = get_irn_arity(end);
1124         for (i = 0; i < irn_arity; i++)
1125                 add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
1126
1127         /* The new end node will die.  We need not free as the in array is on the obstack:
1128            copy_node() only generated 'D' arrays. */
1129
1130         /* -- Replace Return nodes by Jump nodes. -- */
1131         n_ret = 0;
1132         for (i = 0; i < arity; i++) {
1133                 ir_node *ret;
1134                 ret = get_irn_n(end_bl, i);
1135                 if (is_Return(ret)) {
1136                         cf_pred[n_ret] = new_r_Jmp(current_ir_graph, get_nodes_block(ret));
1137                         n_ret++;
1138                 }
1139         }
1140         set_irn_in(post_bl, n_ret, cf_pred);
1141
1142         /* -- Build a Tuple for all results of the method.
1143            Add Phi node if there was more than one Return.  -- */
1144         turn_into_tuple(post_call, 4);
1145         /* First the Memory-Phi */
1146         n_ret = 0;
1147         for (i = 0; i < arity; i++) {
1148                 ret = get_irn_n(end_bl, i);
1149                 if (is_Return(ret)) {
1150                         cf_pred[n_ret] = get_Return_mem(ret);
1151                         n_ret++;
1152                 }
1153         }
1154         phi = new_Phi(n_ret, cf_pred, mode_M);
1155         set_Tuple_pred(call, pn_Call_M_regular, phi);
1156         /* Conserve Phi-list for further inlinings -- but might be optimized */
1157         if (get_nodes_block(phi) == post_bl) {
1158                 set_irn_link(phi, get_irn_link(post_bl));
1159                 set_irn_link(post_bl, phi);
1160         }
1161         /* Now the real results */
1162         if (n_res > 0) {
1163                 for (j = 0; j < n_res; j++) {
1164                         n_ret = 0;
1165                         for (i = 0; i < arity; i++) {
1166                                 ret = get_irn_n(end_bl, i);
1167                                 if (get_irn_op(ret) == op_Return) {
1168                                         cf_pred[n_ret] = get_Return_res(ret, j);
1169                                         n_ret++;
1170                                 }
1171                         }
1172                         if (n_ret > 0)
1173                                 phi = new_Phi(n_ret, cf_pred, get_irn_mode(cf_pred[0]));
1174                         else
1175                                 phi = new_Bad();
1176                         res_pred[j] = phi;
1177                         /* Conserve Phi-list for further inlinings -- but might be optimized */
1178                         if (get_nodes_block(phi) == post_bl) {
1179                                 set_irn_link(phi, get_irn_link(post_bl));
1180                                 set_irn_link(post_bl, phi);
1181                         }
1182                 }
1183                 set_Tuple_pred(call, pn_Call_T_result, new_Tuple(n_res, res_pred));
1184         } else {
1185                 set_Tuple_pred(call, pn_Call_T_result, new_Bad());
1186         }
1187         /* Finally the exception control flow.
1188            We have two (three) possible situations:
1189            First if the Call branches to an exception handler: We need to add a Phi node to
1190            collect the memory containing the exception objects.  Further we need
1191            to add another block to get a correct representation of this Phi.  To
1192            this block we add a Jmp that resolves into the X output of the Call
1193            when the Call is turned into a tuple.
1194            Second the Call branches to End, the exception is not handled.  Just
1195            add all inlined exception branches to the End node.
1196            Third: there is no Exception edge at all. Handle as case two. */
1197         if (exc_handling == 0) {
1198                 n_exc = 0;
1199                 for (i = 0; i < arity; i++) {
1200                         ir_node *ret;
1201                         ret = get_irn_n(end_bl, i);
1202                         if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
1203                                 cf_pred[n_exc] = ret;
1204                                 n_exc++;
1205                         }
1206                 }
1207                 if (n_exc > 0) {
1208                         new_Block(n_exc, cf_pred);      /* watch it: current_block is changed! */
1209                         set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
1210                         /* The Phi for the memories with the exception objects */
1211                         n_exc = 0;
1212                         for (i = 0; i < arity; i++) {
1213                                 ir_node *ret;
1214                                 ret = skip_Proj(get_irn_n(end_bl, i));
1215                                 if (is_Call(ret)) {
1216                                         cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 3);
1217                                         n_exc++;
1218                                 } else if (is_fragile_op(ret)) {
1219                                         /* We rely that all cfops have the memory output at the same position. */
1220                                         cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 0);
1221                                         n_exc++;
1222                                 } else if (get_irn_op(ret) == op_Raise) {
1223                                         cf_pred[n_exc] = new_r_Proj(current_ir_graph, get_nodes_block(ret), ret, mode_M, 1);
1224                                         n_exc++;
1225                                 }
1226                         }
1227                         set_Tuple_pred(call, pn_Call_M_except, new_Phi(n_exc, cf_pred, mode_M));
1228                 } else {
1229                         set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1230                         set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1231                 }
1232         } else {
1233                 ir_node *main_end_bl;
1234                 int main_end_bl_arity;
1235                 ir_node **end_preds;
1236
1237                 /* assert(exc_handling == 1 || no exceptions. ) */
1238                 n_exc = 0;
1239                 for (i = 0; i < arity; i++) {
1240                         ir_node *ret = get_irn_n(end_bl, i);
1241
1242                         if (is_fragile_op(skip_Proj(ret)) || (get_irn_op(skip_Proj(ret)) == op_Raise)) {
1243                                 cf_pred[n_exc] = ret;
1244                                 n_exc++;
1245                         }
1246                 }
1247                 main_end_bl = get_irg_end_block(current_ir_graph);
1248                 main_end_bl_arity = get_irn_arity(main_end_bl);
1249                 end_preds =  xmalloc ((n_exc + main_end_bl_arity) * sizeof(*end_preds));
1250
1251                 for (i = 0; i < main_end_bl_arity; ++i)
1252                         end_preds[i] = get_irn_n(main_end_bl, i);
1253                 for (i = 0; i < n_exc; ++i)
1254                         end_preds[main_end_bl_arity + i] = cf_pred[i];
1255                 set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
1256                 set_Tuple_pred(call, pn_Call_X_except, new_Bad());
1257                 set_Tuple_pred(call, pn_Call_M_except, new_Bad());
1258                 free(end_preds);
1259         }
1260         free(res_pred);
1261         free(cf_pred);
1262
1263         /* --  Turn CSE back on. -- */
1264         set_optimize(rem_opt);
1265
1266         return 1;
1267 }
1268
1269 /********************************************************************/
1270 /* Apply inlineing to small methods.                                */
1271 /********************************************************************/
1272
1273 /** Represents a possible inlinable call in a graph. */
1274 typedef struct _call_entry call_entry;
1275 struct _call_entry {
1276         ir_node    *call;   /**< the Call */
1277         ir_graph   *callee; /**< the callee called here */
1278         call_entry *next;   /**< for linking the next one */
1279 };
1280
1281 /**
1282  * environment for inlining small irgs
1283  */
1284 typedef struct _inline_env_t {
1285         struct obstack obst;  /**< an obstack where call_entries are allocated on. */
1286         call_entry *head;     /**< the head of the call entry list */
1287         call_entry *tail;     /**< the tail of the call entry list */
1288 } inline_env_t;
1289
1290 /**
1291  * Returns the irg called from a Call node. If the irg is not
1292  * known, NULL is returned.
1293  */
1294 static ir_graph *get_call_called_irg(ir_node *call) {
1295         ir_node *addr;
1296         ir_graph *called_irg = NULL;
1297
1298         addr = get_Call_ptr(call);
1299         if (is_SymConst(addr) && get_SymConst_kind(addr) == symconst_addr_ent) {
1300                 called_irg = get_entity_irg(get_SymConst_entity(addr));
1301         }
1302
1303         return called_irg;
1304 }
1305
1306 /**
1307  * Walker: Collect all calls to known graphs inside a graph.
1308  */
1309 static void collect_calls(ir_node *call, void *env) {
1310         if (is_Call(call)) {
1311                 ir_graph *called_irg = get_call_called_irg(call);
1312                 if (called_irg) {
1313                         /* The Call node calls a locally defined method.  Remember to inline. */
1314                         inline_env_t *ienv  = env;
1315                         call_entry   *entry = obstack_alloc(&ienv->obst, sizeof(*entry));
1316                         entry->call   = call;
1317                         entry->callee = called_irg;
1318                         entry->next   = NULL;
1319
1320                         if (ienv->tail == NULL)
1321                                 ienv->head = entry;
1322                         else
1323                                 ienv->tail->next = entry;
1324                         ienv->tail = entry;
1325                 }
1326         }
1327 }
1328
1329 /**
1330  * Inlines all small methods at call sites where the called address comes
1331  * from a Const node that references the entity representing the called
1332  * method.
1333  * The size argument is a rough measure for the code size of the method:
1334  * Methods where the obstack containing the firm graph is smaller than
1335  * size are inlined.
1336  */
1337 void inline_small_irgs(ir_graph *irg, int size) {
1338   ir_graph *rem = current_ir_graph;
1339         inline_env_t env;
1340         call_entry *entry;
1341         DEBUG_ONLY(firm_dbg_module_t *dbg;)
1342
1343         if (!(get_opt_optimize() && get_opt_inline())) return;
1344
1345         FIRM_DBG_REGISTER(dbg, "firm.opt.inline");
1346
1347         current_ir_graph = irg;
1348         /* Handle graph state */
1349         assert(get_irg_phase_state(irg) != phase_building);
1350         free_callee_info(irg);
1351
1352         /* Find Call nodes to inline.
1353            (We can not inline during a walk of the graph, as inlineing the same
1354            method several times changes the visited flag of the walked graph:
1355            after the first inlineing visited of the callee equals visited of
1356            the caller.  With the next inlineing both are increased.) */
1357         obstack_init(&env.obst);
1358         env.head = env.tail = NULL;
1359         irg_walk_graph(irg, NULL, collect_calls, &env);
1360
1361         if (env.head != NULL) {
1362                 /* There are calls to inline */
1363                 collect_phiprojs(irg);
1364                 for (entry = env.head; entry != NULL; entry = entry->next) {
1365                         ir_graph *callee = entry->callee;
1366                         if (((_obstack_memory_used(callee->obst) - (int)obstack_room(callee->obst)) < size) ||
1367                             (get_irg_inline_property(callee) >= irg_inline_forced)) {
1368                                 inline_method(entry->call, callee);
1369                         }
1370                 }
1371         }
1372         obstack_free(&env.obst, NULL);
1373         current_ir_graph = rem;
1374 }
1375
1376 /**
1377  * Environment for inlining irgs.
1378  */
1379 typedef struct {
1380   int n_nodes;             /**< Number of nodes in graph except Id, Tuple, Proj, Start, End. */
1381         int n_nodes_orig;        /**< for statistics */
1382         call_entry *call_head;   /**< The head of the list of all call nodes in this graph. */
1383         call_entry *call_tail;   /**< The tail of the list of all call nodes in this graph .*/
1384         int n_call_nodes;        /**< Number of Call nodes in the graph. */
1385         int n_call_nodes_orig;   /**< for statistics */
1386         int n_callers;           /**< Number of known graphs that call this graphs. */
1387         int n_callers_orig;      /**< for statistics */
1388         int got_inline;          /**< Set, if at leat one call inside this graph was inlined. */
1389 } inline_irg_env;
1390
1391 /**
1392  * Allocate a new environment for inlining.
1393  */
1394 static inline_irg_env *alloc_inline_irg_env(struct obstack *obst) {
1395         inline_irg_env *env    = obstack_alloc(obst, sizeof(*env));
1396         env->n_nodes           = -2; /* do not count count Start, End */
1397         env->n_nodes_orig      = -2; /* do not count Start, End */
1398         env->call_head         = NULL;
1399         env->call_tail         = NULL;
1400         env->n_call_nodes      = 0;
1401         env->n_call_nodes_orig = 0;
1402         env->n_callers         = 0;
1403         env->n_callers_orig    = 0;
1404         env->got_inline        = 0;
1405         return env;
1406 }
1407
1408 typedef struct walker_env {
1409         struct obstack *obst; /**< the obstack for allocations. */
1410         inline_irg_env *x;    /**< the inline environment */
1411         int ignore_runtime;   /**< the ignore runtime flag */
1412 } wenv_t;
1413
1414 /**
1415  * post-walker: collect all calls in the inline-environment
1416  * of a graph and sum some statistics.
1417  */
1418 static void collect_calls2(ir_node *call, void *ctx) {
1419         wenv_t         *env = ctx;
1420         inline_irg_env *x = env->x;
1421         ir_op          *op = get_irn_op(call);
1422         ir_graph       *callee;
1423         call_entry     *entry;
1424
1425         /* count meaningful nodes in irg */
1426         if (op != op_Proj && op != op_Tuple && op != op_Sync) {
1427                 ++x->n_nodes;
1428                 ++x->n_nodes_orig;
1429         }
1430
1431         if (op != op_Call) return;
1432
1433         /* check, if it's a runtime call */
1434         if (env->ignore_runtime) {
1435                 ir_node *symc = get_Call_ptr(call);
1436
1437                 if (is_SymConst(symc) && get_SymConst_kind(symc) == symconst_addr_ent) {
1438                         ir_entity *ent = get_SymConst_entity(symc);
1439
1440                         if (get_entity_additional_properties(ent) & mtp_property_runtime)
1441                                 return;
1442                 }
1443         }
1444
1445         /* collect all call nodes */
1446         ++x->n_call_nodes;
1447         ++x->n_call_nodes_orig;
1448
1449         callee = get_call_called_irg(call);
1450         if (callee) {
1451                 inline_irg_env *callee_env = get_irg_link(callee);
1452                 /* count all static callers */
1453                 ++callee_env->n_callers;
1454                 ++callee_env->n_callers_orig;
1455
1456                 /* link it in the list of possible inlinable entries */
1457                 entry = obstack_alloc(env->obst, sizeof(*entry));
1458                 entry->call   = call;
1459                 entry->callee = callee;
1460                 entry->next   = NULL;
1461                 if (x->call_tail == NULL)
1462                         x->call_head = entry;
1463                 else
1464                         x->call_tail->next = entry;
1465                 x->call_tail = entry;
1466         }
1467 }
1468
1469 /**
1470  * Returns TRUE if the number of callers in 0 in the irg's environment,
1471  * hence this irg is a leave.
1472  */
1473 INLINE static int is_leave(ir_graph *irg) {
1474         inline_irg_env *env = get_irg_link(irg);
1475         return env->n_call_nodes == 0;
1476 }
1477
1478 /**
1479  * Returns TRUE if the number of callers is smaller size in the irg's environment.
1480  */
1481 INLINE static int is_smaller(ir_graph *callee, int size) {
1482         inline_irg_env *env = get_irg_link(callee);
1483         return env->n_nodes < size;
1484 }
1485
1486 /**
1487  * Append the nodes of the list src to the nodes of the list in environment dst.
1488  */
1489 static void append_call_list(struct obstack *obst, inline_irg_env *dst, call_entry *src) {
1490         call_entry *entry, *nentry;
1491
1492         /* Note that the src list points to Call nodes in the inlined graph, but
1493            we need Call nodes in our graph. Luckily the inliner leaves this information
1494            in the link field. */
1495         for (entry = src; entry != NULL; entry = entry->next) {
1496                 nentry = obstack_alloc(obst, sizeof(*nentry));
1497                 nentry->call   = get_irn_link(entry->call);
1498                 nentry->callee = entry->callee;
1499                 nentry->next   = NULL;
1500                 dst->call_tail->next = nentry;
1501                 dst->call_tail       = nentry;
1502         }
1503 }
1504
1505 /*
1506  * Inlines small leave methods at call sites where the called address comes
1507  * from a Const node that references the entity representing the called
1508  * method.
1509  * The size argument is a rough measure for the code size of the method:
1510  * Methods where the obstack containing the firm graph is smaller than
1511  * size are inlined.
1512  */
1513 void inline_leave_functions(int maxsize, int leavesize, int size, int ignore_runtime) {
1514         inline_irg_env   *env;
1515         ir_graph         *irg;
1516         int              i, n_irgs;
1517         ir_graph         *rem;
1518         int              did_inline;
1519         wenv_t           wenv;
1520         call_entry       *entry, *tail;
1521         const call_entry *centry;
1522         struct obstack   obst;
1523         DEBUG_ONLY(firm_dbg_module_t *dbg;)
1524
1525         if (!(get_opt_optimize() && get_opt_inline())) return;
1526
1527         FIRM_DBG_REGISTER(dbg, "firm.opt.inline");
1528         rem = current_ir_graph;
1529         obstack_init(&obst);
1530
1531         /* extend all irgs by a temporary data structure for inlining. */
1532         n_irgs = get_irp_n_irgs();
1533         for (i = 0; i < n_irgs; ++i)
1534                 set_irg_link(get_irp_irg(i), alloc_inline_irg_env(&obst));
1535
1536         /* Precompute information in temporary data structure. */
1537         wenv.obst           = &obst;
1538         wenv.ignore_runtime = ignore_runtime;
1539         for (i = 0; i < n_irgs; ++i) {
1540                 ir_graph *irg = get_irp_irg(i);
1541
1542                 assert(get_irg_phase_state(irg) != phase_building);
1543                 free_callee_info(irg);
1544
1545                 wenv.x = get_irg_link(irg);
1546                 irg_walk_graph(irg, NULL, collect_calls2, &wenv);
1547         }
1548
1549         /* -- and now inline. -- */
1550
1551         /* Inline leaves recursively -- we might construct new leaves. */
1552         do {
1553                 did_inline = 0;
1554
1555                 for (i = 0; i < n_irgs; ++i) {
1556                         ir_node *call;
1557                         int phiproj_computed = 0;
1558
1559                         current_ir_graph = get_irp_irg(i);
1560                         env = (inline_irg_env *)get_irg_link(current_ir_graph);
1561
1562                         tail = NULL;
1563                         for (entry = env->call_head; entry != NULL; entry = entry->next) {
1564                                 ir_graph *callee;
1565
1566                                 if (env->n_nodes > maxsize) break;
1567
1568                                 call   = entry->call;
1569                                 callee = entry->callee;
1570
1571                                 if (is_leave(callee) && is_smaller(callee, leavesize)) {
1572                                         if (!phiproj_computed) {
1573                                                 phiproj_computed = 1;
1574                                                 collect_phiprojs(current_ir_graph);
1575                                         }
1576                                         did_inline = inline_method(call, callee);
1577
1578                                         if (did_inline) {
1579                                                 /* Do some statistics */
1580                                                 inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1581
1582                                                 env->got_inline = 1;
1583                                                 --env->n_call_nodes;
1584                                                 env->n_nodes += callee_env->n_nodes;
1585                                                 --callee_env->n_callers;
1586
1587                                                 /* remove this call from the list */
1588                                                 if (tail != NULL)
1589                                                         tail->next = entry->next;
1590                                                 else
1591                                                         env->call_head = entry->next;
1592                                                 continue;
1593                                         }
1594                                 }
1595                                 tail = entry;
1596                         }
1597                         env->call_tail = tail;
1598                 }
1599         } while (did_inline);
1600
1601         /* inline other small functions. */
1602         for (i = 0; i < n_irgs; ++i) {
1603                 ir_node *call;
1604                 int phiproj_computed = 0;
1605
1606                 current_ir_graph = get_irp_irg(i);
1607                 env = (inline_irg_env *)get_irg_link(current_ir_graph);
1608
1609                 /* note that the list of possible calls is updated during the process */
1610                 tail = NULL;
1611                 for (entry = env->call_head; entry != NULL; entry = entry->next) {
1612                         ir_graph *callee;
1613
1614                         call   = entry->call;
1615                         callee = entry->callee;
1616
1617                         if (((is_smaller(callee, size) && (env->n_nodes < maxsize)) ||    /* small function */
1618                                 (get_irg_inline_property(callee) >= irg_inline_forced))) {
1619                                 if (!phiproj_computed) {
1620                                         phiproj_computed = 1;
1621                                         collect_phiprojs(current_ir_graph);
1622                                 }
1623                                 if (inline_method(call, callee)) {
1624                                         inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee);
1625
1626                                         /* callee was inline. Append it's call list. */
1627                                         env->got_inline = 1;
1628                                         --env->n_call_nodes;
1629                                         append_call_list(&obst, env, callee_env->call_head);
1630                                         env->n_call_nodes += callee_env->n_call_nodes;
1631                                         env->n_nodes += callee_env->n_nodes;
1632                                         --callee_env->n_callers;
1633
1634                                         /* after we have inlined callee, all called methods inside callee
1635                                            are now called once more */
1636                                         for (centry = callee_env->call_head; centry != NULL; centry = centry->next) {
1637                                                 inline_irg_env *penv = get_irg_link(centry->callee);
1638                                                 ++penv->n_callers;
1639                                         }
1640
1641                                         /* remove this call from the list */
1642                                         if (tail != NULL)
1643                                                 tail->next = entry->next;
1644                                         else
1645                                                 env->call_head = entry->next;
1646                                         continue;
1647                                 }
1648                         }
1649                         tail = entry;
1650                 }
1651                 env->call_tail = tail;
1652         }
1653
1654         for (i = 0; i < n_irgs; ++i) {
1655                 irg = get_irp_irg(i);
1656                 env = (inline_irg_env *)get_irg_link(irg);
1657
1658                 if (env->got_inline) {
1659                         /* this irg got calls inlined */
1660                         set_irg_outs_inconsistent(irg);
1661                         set_irg_doms_inconsistent(irg);
1662
1663                         optimize_graph_df(irg);
1664                         optimize_cf(irg);
1665                 }
1666                 if (env->got_inline || (env->n_callers_orig != env->n_callers))
1667                         DB((dbg, SET_LEVEL_1, "Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
1668                         env->n_nodes_orig, env->n_nodes, env->n_call_nodes_orig, env->n_call_nodes,
1669                         env->n_callers_orig, env->n_callers,
1670                         get_entity_name(get_irg_entity(irg))));
1671         }
1672
1673         obstack_free(&obst, NULL);
1674         current_ir_graph = rem;
1675 }
1676
1677 /*******************************************************************/
1678 /*  Code Placement.  Pins all floating nodes to a block where they */
1679 /*  will be executed only if needed.                               */
1680 /*******************************************************************/
1681
1682 /**
1683  * Returns non-zero, is a block is not reachable from Start.
1684  *
1685  * @param block  the block to test
1686  */
1687 static int
1688 is_Block_unreachable(ir_node *block) {
1689         return is_Block_dead(block) || get_Block_dom_depth(block) < 0;
1690 }
1691
1692 /**
1693  * Find the earliest correct block for node n.  --- Place n into the
1694  * same Block as its dominance-deepest Input.
1695  *
1696  * We have to avoid calls to get_nodes_block() here
1697  * because the graph is floating.
1698  *
1699  * move_out_of_loops() expects that place_floats_early() have placed
1700  * all "living" nodes into a living block. That's why we must
1701  * move nodes in dead block with "live" successors into a valid
1702  * block.
1703  * We move them just into the same block as it's successor (or
1704  * in case of a Phi into the effective use block). For Phi successors,
1705  * this may still be a dead block, but then there is no real use, as
1706  * the control flow will be dead later.
1707  *
1708  * @param n         the node to be placed
1709  * @param worklist  a worklist, predecessors of non-floating nodes are placed here
1710  */
1711 static void
1712 place_floats_early(ir_node *n, waitq *worklist) {
1713         int i, irn_arity;
1714
1715         /* we must not run into an infinite loop */
1716         assert(irn_not_visited(n));
1717         mark_irn_visited(n);
1718
1719         /* Place floating nodes. */
1720         if (get_irn_pinned(n) == op_pin_state_floats) {
1721                 ir_node *curr_block = get_irn_n(n, -1);
1722                 int in_dead_block   = is_Block_unreachable(curr_block);
1723                 int depth           = 0;
1724                 ir_node *b          = NULL;   /* The block to place this node in */
1725
1726                 assert(is_no_Block(n));
1727
1728                 if (is_irn_start_block_placed(n)) {
1729                         /* These nodes will not be placed by the loop below. */
1730                         b = get_irg_start_block(current_ir_graph);
1731                         depth = 1;
1732                 }
1733
1734                 /* find the block for this node. */
1735                 irn_arity = get_irn_arity(n);
1736                 for (i = 0; i < irn_arity; i++) {
1737                         ir_node *pred = get_irn_n(n, i);
1738                         ir_node *pred_block;
1739
1740                         if ((irn_not_visited(pred))
1741                             && (get_irn_pinned(pred) == op_pin_state_floats)) {
1742
1743                                 /*
1744                                  * If the current node is NOT in a dead block, but one of its
1745                                  * predecessors is, we must move the predecessor to a live block.
1746                                  * Such thing can happen, if global CSE chose a node from a dead block.
1747                                  * We move it simply to our block.
1748                                  * Note that neither Phi nor End nodes are floating, so we don't
1749                                  * need to handle them here.
1750                                  */
1751                                 if (! in_dead_block) {
1752                                         if (get_irn_pinned(pred) == op_pin_state_floats &&
1753                                                 is_Block_unreachable(get_irn_n(pred, -1)))
1754                                                 set_nodes_block(pred, curr_block);
1755                                 }
1756                                 place_floats_early(pred, worklist);
1757                         }
1758
1759                         /*
1760                          * A node in the Bad block must stay in the bad block,
1761                          * so don't compute a new block for it.
1762                          */
1763                         if (in_dead_block)
1764                                 continue;
1765
1766                         /* Because all loops contain at least one op_pin_state_pinned node, now all
1767                            our inputs are either op_pin_state_pinned or place_early() has already
1768                            been finished on them.  We do not have any unfinished inputs!  */
1769                         pred_block = get_irn_n(pred, -1);
1770                         if ((!is_Block_dead(pred_block)) &&
1771                                 (get_Block_dom_depth(pred_block) > depth)) {
1772                                 b = pred_block;
1773                                 depth = get_Block_dom_depth(pred_block);
1774                         }
1775                         /* Avoid that the node is placed in the Start block */
1776                         if ((depth == 1) && (get_Block_dom_depth(get_irn_n(n, -1)) > 1)
1777                                 && get_irg_phase_state(current_ir_graph) != phase_backend) {
1778                                 b = get_Block_cfg_out(get_irg_start_block(current_ir_graph), 0);
1779                                 assert(b != get_irg_start_block(current_ir_graph));
1780                                 depth = 2;
1781                         }
1782                 }
1783                 if (b)
1784                         set_nodes_block(n, b);
1785         }
1786
1787         /*
1788          * Add predecessors of non floating nodes and non-floating predecessors
1789          * of floating nodes to worklist and fix their blocks if the are in dead block.
1790          */
1791         irn_arity = get_irn_arity(n);
1792
1793         if (get_irn_op(n) == op_End) {
1794                 /*
1795                  * Simplest case: End node. Predecessors are keep-alives,
1796                  * no need to move out of dead block.
1797                  */
1798                 for (i = -1; i < irn_arity; ++i) {
1799                         ir_node *pred = get_irn_n(n, i);
1800                         if (irn_not_visited(pred))
1801                                 waitq_put(worklist, pred);
1802                 }
1803         } else if (is_Block(n)) {
1804                 /*
1805                  * Blocks: Predecessors are control flow, no need to move
1806                  * them out of dead block.
1807                  */
1808                 for (i = irn_arity - 1; i >= 0; --i) {
1809                         ir_node *pred = get_irn_n(n, i);
1810                         if (irn_not_visited(pred))
1811                                 waitq_put(worklist, pred);
1812                 }
1813         } else if (is_Phi(n)) {
1814                 ir_node *pred;
1815                 ir_node *curr_block = get_irn_n(n, -1);
1816                 int in_dead_block   = is_Block_unreachable(curr_block);
1817
1818                 /*
1819                  * Phi nodes: move nodes from dead blocks into the effective use
1820                  * of the Phi-input if the Phi is not in a bad block.
1821                  */
1822                 pred = get_irn_n(n, -1);
1823                 if (irn_not_visited(pred))
1824                         waitq_put(worklist, pred);
1825
1826                 for (i = irn_arity - 1; i >= 0; --i) {
1827                         ir_node *pred = get_irn_n(n, i);
1828
1829                         if (irn_not_visited(pred)) {
1830                                 if (! in_dead_block &&
1831                                         get_irn_pinned(pred) == op_pin_state_floats &&
1832                                         is_Block_unreachable(get_irn_n(pred, -1))) {
1833                                         set_nodes_block(pred, get_Block_cfgpred_block(curr_block, i));
1834                                 }
1835                                 waitq_put(worklist, pred);
1836                         }
1837                 }
1838         } else {
1839                 ir_node *pred;
1840                 ir_node *curr_block = get_irn_n(n, -1);
1841                 int in_dead_block   = is_Block_unreachable(curr_block);
1842
1843                 /*
1844                  * All other nodes: move nodes from dead blocks into the same block.
1845                  */
1846                 pred = get_irn_n(n, -1);
1847                 if (irn_not_visited(pred))
1848                         waitq_put(worklist, pred);
1849
1850                 for (i = irn_arity - 1; i >= 0; --i) {
1851                         ir_node *pred = get_irn_n(n, i);
1852
1853                         if (irn_not_visited(pred)) {
1854                                 if (! in_dead_block &&
1855                                         get_irn_pinned(pred) == op_pin_state_floats &&
1856                                         is_Block_unreachable(get_irn_n(pred, -1))) {
1857                                         set_nodes_block(pred, curr_block);
1858                                 }
1859                                 waitq_put(worklist, pred);
1860                         }
1861                 }
1862         }
1863 }
1864
1865 /**
1866  * Floating nodes form subgraphs that begin at nodes as Const, Load,
1867  * Start, Call and that end at op_pin_state_pinned nodes as Store, Call.  Place_early
1868  * places all floating nodes reachable from its argument through floating
1869  * nodes and adds all beginnings at op_pin_state_pinned nodes to the worklist.
1870  *
1871  * @param worklist   a worklist, used for the algorithm, empty on in/output
1872  */
1873 static void place_early(waitq *worklist) {
1874         assert(worklist);
1875         inc_irg_visited(current_ir_graph);
1876
1877         /* this inits the worklist */
1878         place_floats_early(get_irg_end(current_ir_graph), worklist);
1879
1880         /* Work the content of the worklist. */
1881         while (!waitq_empty(worklist)) {
1882                 ir_node *n = waitq_get(worklist);
1883                 if (irn_not_visited(n))
1884                         place_floats_early(n, worklist);
1885         }
1886
1887         set_irg_outs_inconsistent(current_ir_graph);
1888         set_irg_pinned(current_ir_graph, op_pin_state_pinned);
1889 }
1890
1891 /**
1892  * Compute the deepest common ancestor of block and dca.
1893  */
1894 static ir_node *calc_dca(ir_node *dca, ir_node *block) {
1895         assert(block);
1896
1897         /* we do not want to place nodes in dead blocks */
1898         if (is_Block_dead(block))
1899                 return dca;
1900
1901         /* We found a first legal placement. */
1902         if (!dca) return block;
1903
1904         /* Find a placement that is dominates both, dca and block. */
1905         while (get_Block_dom_depth(block) > get_Block_dom_depth(dca))
1906                 block = get_Block_idom(block);
1907
1908         while (get_Block_dom_depth(dca) > get_Block_dom_depth(block)) {
1909                 dca = get_Block_idom(dca);
1910         }
1911
1912         while (block != dca) {
1913                 block = get_Block_idom(block); dca = get_Block_idom(dca);
1914         }
1915
1916         return dca;
1917 }
1918
1919 /** Deepest common dominance ancestor of DCA and CONSUMER of PRODUCER.
1920  * I.e., DCA is the block where we might place PRODUCER.
1921  * A data flow edge points from producer to consumer.
1922  */
1923 static ir_node *
1924 consumer_dom_dca(ir_node *dca, ir_node *consumer, ir_node *producer) {
1925         ir_node *block = NULL;
1926
1927         /* Compute the latest block into which we can place a node so that it is
1928            before consumer. */
1929         if (get_irn_op(consumer) == op_Phi) {
1930                 /* our consumer is a Phi-node, the effective use is in all those
1931                    blocks through which the Phi-node reaches producer */
1932                 int i, irn_arity;
1933                 ir_node *phi_block = get_nodes_block(consumer);
1934                 irn_arity = get_irn_arity(consumer);
1935
1936                 for (i = 0;  i < irn_arity; i++) {
1937                         if (get_irn_n(consumer, i) == producer) {
1938                                 ir_node *new_block = get_nodes_block(get_Block_cfgpred(phi_block, i));
1939
1940                                 if (! is_Block_unreachable(new_block))
1941                                         block = calc_dca(block, new_block);
1942                         }
1943                 }
1944
1945                 if (! block)
1946                         block = get_irn_n(producer, -1);
1947         } else {
1948                 assert(is_no_Block(consumer));
1949                 block = get_nodes_block(consumer);
1950         }
1951
1952         /* Compute the deepest common ancestor of block and dca. */
1953         return calc_dca(dca, block);
1954 }
1955
1956 /* FIXME: the name clashes here with the function from ana/field_temperature.c
1957  * please rename. */
1958 static INLINE int get_irn_loop_depth(ir_node *n) {
1959         return get_loop_depth(get_irn_loop(n));
1960 }
1961
1962 /**
1963  * Move n to a block with less loop depth than it's current block. The
1964  * new block must be dominated by early.
1965  *
1966  * @param n      the node that should be moved
1967  * @param early  the earliest block we can n move to
1968  */
1969 static void move_out_of_loops(ir_node *n, ir_node *early) {
1970         ir_node *best, *dca;
1971         assert(n && early);
1972
1973
1974         /* Find the region deepest in the dominator tree dominating
1975            dca with the least loop nesting depth, but still dominated
1976            by our early placement. */
1977         dca = get_nodes_block(n);
1978
1979         best = dca;
1980         while (dca != early) {
1981                 dca = get_Block_idom(dca);
1982                 if (!dca || is_Bad(dca)) break; /* may be Bad if not reachable from Start */
1983                 if (get_irn_loop_depth(dca) < get_irn_loop_depth(best)) {
1984                         best = dca;
1985                 }
1986         }
1987         if (best != get_nodes_block(n)) {
1988                 /* debug output
1989                 printf("Moving out of loop: "); DDMN(n);
1990                 printf(" Outermost block: "); DDMN(early);
1991                 printf(" Best block: "); DDMN(best);
1992                 printf(" Innermost block: "); DDMN(get_nodes_block(n));
1993                 */
1994                 set_nodes_block(n, best);
1995         }
1996 }
1997
1998 /**
1999  * Find the latest legal block for N and place N into the
2000  * `optimal' Block between the latest and earliest legal block.
2001  * The `optimal' block is the dominance-deepest block of those
2002  * with the least loop-nesting-depth.  This places N out of as many
2003  * loops as possible and then makes it as control dependent as
2004  * possible.
2005  *
2006  * @param n         the node to be placed
2007  * @param worklist  a worklist, all successors of non-floating nodes are
2008  *                  placed here
2009  */
2010 static void place_floats_late(ir_node *n, pdeq *worklist) {
2011   int i;
2012         ir_node *early_blk;
2013
2014         assert(irn_not_visited(n)); /* no multiple placement */
2015
2016         mark_irn_visited(n);
2017
2018         /* no need to place block nodes, control nodes are already placed. */
2019         if ((get_irn_op(n) != op_Block) &&
2020             (!is_cfop(n)) &&
2021             (get_irn_mode(n) != mode_X)) {
2022                 /* Remember the early_blk placement of this block to move it
2023                    out of loop no further than the early_blk placement. */
2024                 early_blk = get_irn_n(n, -1);
2025
2026                 /*
2027                  * BEWARE: Here we also get code, that is live, but
2028                  * was in a dead block.  If the node is life, but because
2029                  * of CSE in a dead block, we still might need it.
2030                  */
2031
2032                 /* Assure that our users are all placed, except the Phi-nodes.
2033                 --- Each data flow cycle contains at least one Phi-node.  We
2034                     have to break the `user has to be placed before the
2035                     producer' dependence cycle and the Phi-nodes are the
2036                     place to do so, because we need to base our placement on the
2037                     final region of our users, which is OK with Phi-nodes, as they
2038                     are op_pin_state_pinned, and they never have to be placed after a
2039                     producer of one of their inputs in the same block anyway. */
2040                 for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
2041                         ir_node *succ = get_irn_out(n, i);
2042                         if (irn_not_visited(succ) && (get_irn_op(succ) != op_Phi))
2043                                 place_floats_late(succ, worklist);
2044                 }
2045
2046                 if (! is_Block_dead(early_blk)) {
2047                         /* do only move things that where not dead */
2048                         ir_op *op = get_irn_op(n);
2049
2050                         /* We have to determine the final block of this node... except for
2051                            constants and Projs */
2052                         if ((get_irn_pinned(n) == op_pin_state_floats) &&
2053                             (op != op_Const)    &&
2054                             (op != op_SymConst) &&
2055                             (op != op_Proj))
2056                         {
2057                                 ir_node *dca = NULL;  /* deepest common ancestor in the
2058                                                                                  dominator tree of all nodes'
2059                                                                                  blocks depending on us; our final
2060                                                                                  placement has to dominate DCA. */
2061                                 for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
2062                                         ir_node *succ = get_irn_out(n, i);
2063                                         ir_node *succ_blk;
2064
2065                                         if (get_irn_op(succ) == op_End) {
2066                                                 /*
2067                                                  * This consumer is the End node, a keep alive edge.
2068                                                  * This is not a real consumer, so we ignore it
2069                                                  */
2070                                                 continue;
2071                                         }
2072
2073                                         /* ignore if succ is in dead code */
2074                                         succ_blk = get_irn_n(succ, -1);
2075                                         if (is_Block_unreachable(succ_blk))
2076                                                 continue;
2077                                         dca = consumer_dom_dca(dca, succ, n);
2078                                 }
2079                                 if (dca) {
2080                                         set_nodes_block(n, dca);
2081                                         move_out_of_loops(n, early_blk);
2082                                 }
2083                         }
2084                 }
2085         }
2086
2087         /* Add successors of all non-floating nodes on list. (Those of floating
2088            nodes are placed already and therefore are marked.)  */
2089         for (i = 0; i < get_irn_n_outs(n); i++) {
2090                 ir_node *succ = get_irn_out(n, i);
2091                 if (irn_not_visited(get_irn_out(n, i))) {
2092                         pdeq_putr(worklist, succ);
2093                 }
2094         }
2095 }
2096
2097 /**
2098  * Place floating nodes on the given worklist as late as possible using
2099  * the dominance tree.
2100  *
2101  * @param worklist   the worklist containing the nodes to place
2102  */
2103 static void place_late(waitq *worklist) {
2104         assert(worklist);
2105         inc_irg_visited(current_ir_graph);
2106
2107         /* This fills the worklist initially. */
2108         place_floats_late(get_irg_start_block(current_ir_graph), worklist);
2109
2110         /* And now empty the worklist again... */
2111         while (!waitq_empty(worklist)) {
2112                 ir_node *n = waitq_get(worklist);
2113                 if (irn_not_visited(n))
2114                         place_floats_late(n, worklist);
2115         }
2116 }
2117
2118 /* Code Placement. */
2119 void place_code(ir_graph *irg) {
2120         waitq *worklist;
2121         ir_graph *rem = current_ir_graph;
2122
2123         current_ir_graph = irg;
2124
2125         /* Handle graph state */
2126         assert(get_irg_phase_state(irg) != phase_building);
2127         assure_doms(irg);
2128
2129         if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) {
2130                 free_loop_information(irg);
2131                 construct_backedges(irg);
2132         }
2133
2134         /* Place all floating nodes as early as possible. This guarantees
2135          a legal code placement. */
2136         worklist = new_waitq();
2137         place_early(worklist);
2138
2139         /* place_early() invalidates the outs, place_late needs them. */
2140         compute_irg_outs(irg);
2141
2142         /* Now move the nodes down in the dominator tree. This reduces the
2143            unnecessary executions of the node. */
2144         place_late(worklist);
2145
2146         set_irg_outs_inconsistent(current_ir_graph);
2147         set_irg_loopinfo_inconsistent(current_ir_graph);
2148         del_waitq(worklist);
2149         current_ir_graph = rem;
2150 }
2151
2152 /**
2153  * Called by walker of remove_critical_cf_edges().
2154  *
2155  * Place an empty block to an edge between a blocks of multiple
2156  * predecessors and a block of multiple successors.
2157  *
2158  * @param n   IR node
2159  * @param env Environment of walker. The changed field.
2160  */
2161 static void walk_critical_cf_edges(ir_node *n, void *env) {
2162         int arity, i;
2163         ir_node *pre, *block, *jmp;
2164         int *changed = env;
2165         ir_graph *irg = get_irn_irg(n);
2166
2167         /* Block has multiple predecessors */
2168         arity = get_irn_arity(n);
2169         if (arity > 1) {
2170                 if (n == get_irg_end_block(irg))
2171                         return;  /*  No use to add a block here.      */
2172
2173                 for (i = 0; i < arity; ++i) {
2174                         const ir_op *cfop;
2175
2176                         pre = get_irn_n(n, i);
2177                         cfop = get_irn_op(skip_Proj(pre));
2178                         /* Predecessor has multiple successors. Insert new control flow edge but
2179                            ignore exception edges. */
2180                         if (! is_op_fragile(cfop) && is_op_forking(cfop)) {
2181                                 /* set predecessor of new block */
2182                                 block = new_r_Block(irg, 1, &pre);
2183                                 /* insert new jmp node to new block */
2184                                 jmp = new_r_Jmp(irg, block);
2185                                 /* set successor of new block */
2186                                 set_irn_n(n, i, jmp);
2187                                 *changed = 1;
2188                         } /* predecessor has multiple successors */
2189                 } /* for all predecessors */
2190         } /* n is a multi-entry block */
2191 }
2192
2193 void remove_critical_cf_edges(ir_graph *irg) {
2194         int changed = 0;
2195
2196         irg_block_walk_graph(irg, NULL, walk_critical_cf_edges, &changed);
2197         if (changed) {
2198                 /* control flow changed */
2199                 set_irg_outs_inconsistent(irg);
2200                 set_irg_extblk_inconsistent(irg);
2201                 set_irg_doms_inconsistent(irg);
2202                 set_irg_loopinfo_inconsistent(irg);
2203         }
2204 }