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