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