Some minor speed up by rearanging if's
[libfirm] / ir / opt / cfopt.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/opt/cfopt.c
4  * Purpose:     control flow optimizations
5  * Author:
6  * Created:
7  * CVS-ID:      $Id$
8  * Copyright:   (c) 1998-2004 Universität Karlsruhe
9  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
10  */
11
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #ifdef HAVE_MALLOC_H
17 # include <malloc.h>
18 #endif
19 #ifdef HAVE_ALLOCA_H
20 # include <alloca.h>
21 #endif
22
23 #include <assert.h>
24
25 #include "xmalloc.h"
26 #include "irnode_t.h"
27 #include "irgraph_t.h"
28 #include "irprog_t.h"
29
30 #include "ircons.h"
31 #include "iropt_t.h"
32 #include "irgwalk.h"
33 #include "irgmod.h"
34 #include "irdump.h"
35 #include "irvrfy.h"
36
37 #include "array.h"
38
39 #include "irouts.h"
40 #include "irbackedge_t.h"
41
42 #include "irflag_t.h"
43 #include "firmstat.h"
44
45 #include "cfopt.h"
46 #include "iropt_dbg.h"
47
48 /*------------------------------------------------------------------*/
49 /* Control flow optimization.                                       */
50 /*                                                                  */
51 /* Removes Bad control flow predecessors and empty blocks.  A block */
52 /* is empty if it contains only a Jmp node.                         */
53 /* Blocks can only be removed if they are not needed for the        */
54 /* semantics of Phi nodes.                                          */
55 /*------------------------------------------------------------------*/
56
57 /**
58  * Replace binary Conds that jumps twice into the same block
59  * by a simple Jmp.
60  * E.g.
61  * @verbatim
62  *               Cond                     Jmp  Bad
63  *             /       \                   |   /
64  *       ProjX True   ProjX False  ==>     |  /
65  *             \       /                   | /
66  *               Block                    Block
67  * @endverbatim
68  *
69  * Such pattern are the result of if-conversion.
70  *
71  * Note that the simple case that Block has only these two
72  * predecessors are already handled in equivalent_node_Block().
73  */
74 static void remove_senseless_conds(ir_node *bl, void *data)
75 {
76   int i, j;
77   int n = get_Block_n_cfgpreds(bl);
78
79   assert(is_Block(bl));
80
81   for (i = 0; i < n; ++i) {
82     ir_node *pred_i = get_Block_cfgpred(bl, i);
83     ir_node *cond_i = skip_Proj(pred_i);
84
85     if (get_irn_op(cond_i) != op_Cond ||
86         get_irn_mode(get_Cond_selector(cond_i)) != mode_b)
87       continue;
88
89     for (j = i + 1; j < n; ++j) {
90       ir_node *pred_j = get_Block_cfgpred(bl, j);
91       ir_node *cond_j = skip_Proj(pred_j);
92
93       if (cond_j == cond_i) {
94         ir_node *jmp = new_r_Jmp(current_ir_graph, get_nodes_block(cond_i));
95         set_irn_n(bl, i, jmp);
96         set_irn_n(bl, j, new_Bad());
97
98         DBG_OPT_IFSIM2(cond_i, jmp);
99         break;
100       }
101     }
102   }
103 }
104
105
106 /**
107  * Removes Tuples from Block control flow predecessors.
108  * Optimizes blocks with equivalent_node().  This is tricky,
109  * as we want to avoid nodes that have as block predecessor Bads.
110  * Therefore we also optimize at control flow operations, depending
111  * how we first reach the Block.
112  */
113 static void merge_blocks(ir_node *node, void *env) {
114   int i, n;
115   ir_node *new_block;
116
117   /* clear the link field for ALL nodes first */
118   set_irn_link(node, NULL);
119
120   if (is_Block(node)) {
121     /* Remove Tuples */
122
123     /* GL @@@ : is this possible? if (get_opt_normalize()) -- added, all tests go through.
124      A different order of optimizations might cause problems. */
125     if (get_opt_normalize()) {
126       for (i = 0, n = get_Block_n_cfgpreds(node); i < n; ++i)
127         set_Block_cfgpred(node, i, skip_Tuple(get_Block_cfgpred(node, i)));
128     }
129
130     /* see below */
131     new_block = equivalent_node(node);
132     if (new_block != node && ! is_Block_dead(new_block))
133       exchange(node, new_block);
134
135   } else if (get_opt_optimize() && (get_irn_mode(node) == mode_X)) {
136     /* We will soon visit a block.  Optimize it before visiting! */
137     ir_node *b = get_nodes_block(skip_Proj(node));
138
139     if (!is_Block_dead(b)) {
140       new_block = equivalent_node(b);
141
142       while (irn_not_visited(b) && (!is_Block_dead(new_block)) && (new_block != b)) {
143         /* We would have to run gigo() if new is bad, so we
144            promote it directly below. Nevertheless, we sometimes reach a block
145            the first time through a dataflow node.  In this case we optimized the
146            block as such and have to promote the Bad here. */
147         assert((get_opt_control_flow_straightening() ||
148                 get_opt_control_flow_weak_simplification()) &&
149                ("strange flag setting"));
150         exchange (b, new_block);
151         b = new_block;
152         new_block = equivalent_node(b);
153       }
154
155       /* normally, we would create a Bad block here, but this must be
156        * prevented, so just set it's cf to Bad.
157        */
158       if (is_Block_dead(new_block))
159         exchange(node, new_Bad());
160     }
161   }
162 }
163
164 /**
165  * Remove cf from dead block by inspecting dominance info
166  * Do not replace blocks by Bad.  This optimization shall
167  * ensure, that all Bad control flow predecessors are
168  * removed, and no new other Bads are introduced.
169  *
170  * Must be run in the post walker.
171  */
172 static void remove_dead_block_cf(ir_node *block, void *env)
173 {
174   int i, n;
175
176   /* check block predecessors and turn control flow into bad */
177   for (i = 0, n = get_Block_n_cfgpreds(block); i < n; ++i) {
178     ir_node *pred_X = get_Block_cfgpred(block, i);
179
180     if (! is_Bad(pred_X)) {
181       ir_node *pred_bl = get_nodes_block(skip_Proj(pred_X));
182
183       if (is_Block_dead(pred_bl) || (get_Block_dom_depth(pred_bl) < 0))
184         exchange (pred_X, new_Bad());
185     }
186   }
187 }
188
189 /**
190  * Collects all Phi nodes in link list of Block.
191  * Marks all blocks "block_visited" if they contain a node other
192  * than Jmp.
193  * Replaces n by Bad if n is unreachable control flow. We do that
194  * in the post walker, so we catch all blocks.
195  *
196  * Links all Proj nodes to their predecessors.
197  */
198 static void collect_nodes(ir_node *n, void *env) {
199   if (is_no_Block(n)) {
200     ir_node *b  = get_nodes_block(n);
201     ir_op   *op = get_irn_op(n);
202
203     if (op == op_Phi) {
204       /* Collect Phi nodes to compact ins along with block's ins. */
205       set_irn_link(n, get_irn_link(b));
206       set_irn_link(b, n);
207     }
208     else if (op != op_Jmp && !is_Bad(b)) {  /* Check for non empty block. */
209       mark_Block_block_visited(b);
210
211       if (op == op_Proj) {               /* link Proj nodes */
212         ir_node *pred = get_Proj_pred(n);
213
214         set_irn_link(n, get_irn_link(pred));
215         set_irn_link(pred, n);
216       }
217     }
218   }
219 }
220
221 /** Returns true if pred is predecessor of block. */
222 static int is_pred_of(ir_node *pred, ir_node *b) {
223   int i, n;
224
225   for (i = 0, n = get_Block_n_cfgpreds(b); i < n; ++i) {
226     ir_node *b_pred = get_nodes_block(get_Block_cfgpred(b, i));
227     if (b_pred == pred) return 1;
228   }
229   return 0;
230 }
231
232
233 /** Test whether we can optimize away pred block pos of b.
234  *
235  *  @param  b    A block node.
236  *  @param  pos  The position of the predecessor block to judge about.
237  *
238  *  @returns     The number of predecessors
239  *
240  *  The test is rather tricky.
241  *
242  *  The situation is something like the following:
243  *  @verbatim
244  *                 if-block
245  *                  /   \
246  *              then-b  else-b
247  *                  \   /
248  *                    b
249  *  @endverbatim
250  *
251  *  b merges the control flow of an if-then-else.  We may not remove
252  *  the 'then' _and_ the 'else' block of an 'if' if there is a Phi
253  *  node in b, even if both are empty.  The destruction of this Phi
254  *  requires that a copy is added before the merge.  We have to
255  *  keep one of the case blocks to place the copies in.
256  *
257  *  To perform the test for pos, we must regard predecessors before pos
258  *  as already removed.
259  **/
260 static int test_whether_dispensable(ir_node *b, int pos) {
261   int i, j, n_preds = 1;
262   ir_node *pred = get_Block_cfgpred_block(b, pos);
263
264   /* Bad blocks will be optimized away, so we don't need space for them */
265   if (is_Block_dead(pred))
266     return 0;
267
268   if (get_Block_block_visited(pred) + 1
269       < get_irg_block_visited(current_ir_graph)) {
270
271     if (!get_opt_optimize() || !get_opt_control_flow_strong_simplification()) {
272       /* Mark block so that is will not be removed: optimization is turned off. */
273       set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
274       return 1;
275     }
276
277     /* Seems to be empty. At least we detected this in collect_nodes. */
278     if (!get_irn_link(b)) {
279       /* There are no Phi nodes ==> all predecessors are dispensable. */
280       n_preds = get_Block_n_cfgpreds(pred);
281     } else {
282       /* b's pred blocks and pred's pred blocks must be pairwise disjunct.
283          Handle all pred blocks with preds < pos as if they were already removed. */
284       for (i = 0; i < pos; i++) {
285         ir_node *b_pred = get_Block_cfgpred_block(b, i);
286         if (! is_Block_dead(b_pred) &&
287             get_Block_block_visited(b_pred) + 1
288             < get_irg_block_visited(current_ir_graph)) {
289           for (j = 0; j < get_Block_n_cfgpreds(b_pred); j++) {
290             ir_node *b_pred_pred = get_Block_cfgpred_block(b_pred, j);
291             if (is_pred_of(b_pred_pred, pred))
292               goto non_dispensable;
293           }
294         } else {
295           if (is_pred_of(b_pred, pred))
296             goto non_dispensable;
297         }
298       }
299       for (i = pos +1; i < get_Block_n_cfgpreds(b); i++) {
300         ir_node *b_pred = get_Block_cfgpred_block(b, i);
301         if (is_pred_of(b_pred, pred))
302           goto non_dispensable;
303       }
304       /* if we get here, the block is dispensable */
305       n_preds = get_Block_n_cfgpreds(pred);
306     }
307   }
308
309   return n_preds;
310
311 non_dispensable:
312   set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
313   return 1;
314 }
315
316 /**
317  * Store to defer the exchanged of Phi nodes.
318  */
319 typedef struct _defer_ex_phi {
320   ir_node *phi_pred;    /**< the previous Phi node that will be replaced */
321   ir_node *phi;         /**< the new Phi node that replaces phi_pred */
322 } defer_ex_phi;
323
324 /**
325  * handle pre-optimized table switch Cond's
326  */
327 static void handle_switch_cond(ir_node *proj) {
328   ir_node *cond = skip_Proj(proj);
329   ir_node *sel;
330
331   if (! is_Cond(cond))
332     return;
333
334   sel = get_Cond_selector(cond);
335   if (mode_is_int(get_irn_mode(sel))) {
336     /* check for table switch that could be optimized */
337     ir_node *proj1 = get_irn_link(cond);
338     ir_node *proj2 = get_irn_link(proj1);
339     ir_node *jmp, *blk;
340
341     blk = is_Bad(cond) ? cond : get_nodes_block(cond);
342
343     if (! proj2) {
344       /* this Cond has only one Proj: must be the defProj */
345       assert(get_Cond_defaultProj(cond) == get_Proj_proj(proj1));
346       /* convert it into a Jmp */
347       jmp = new_r_Jmp(current_ir_graph, blk);
348       exchange(proj1, jmp);
349     }
350     else if (get_irn_link(proj2) == NULL) {
351       /* We have two Proj's here. Check if the Cond has
352          a constant argument */
353       tarval *tv = value_of(sel);
354
355       if (tv != tarval_bad) {
356         /* we have a constant switch */
357         long num     = get_tarval_long(tv);
358         long def_num = get_Cond_defaultProj(cond);
359
360         if (def_num == get_Proj_proj(proj1)) {
361           /* first one is the defProj */
362           if (num == get_Proj_proj(proj2)) {
363             jmp = new_r_Jmp(current_ir_graph, blk);
364             exchange(proj2, jmp);
365             exchange(proj1, new_Bad());
366           }
367         }
368         else if (def_num == get_Proj_proj(proj2)) {
369           /* second one is the defProj */
370           if (num == get_Proj_proj(proj1)) {
371             jmp = new_r_Jmp(current_ir_graph, blk);
372             exchange(proj1, jmp);
373             exchange(proj2, new_Bad());
374           }
375         }
376         else {
377           /* neither: strange, Cond was not optimized so far */
378           if (num == get_Proj_proj(proj1)) {
379             jmp = new_r_Jmp(current_ir_graph, blk);
380             exchange(proj1, jmp);
381             exchange(proj2, new_Bad());
382           }
383           else if (num == get_Proj_proj(proj2)) {
384             jmp = new_r_Jmp(current_ir_graph, blk);
385             exchange(proj2, jmp);
386             exchange(proj1, new_Bad());
387           }
388         }
389       }
390     }
391   }
392 }
393
394 /**
395  * This method removed Bad cf predecessors from Blocks and Phis, and removes
396  * empty blocks.  A block is empty if it only contains Phi and Jmp nodes.
397  *
398  * We first adapt Phi nodes, then Block nodes, as we need the old ins
399  * of the Block to adapt the Phi nodes.  We do this by computing new
400  * in arrays, and then replacing the old ones.  So far we compute new in arrays
401  * for all nodes, not regarding whether there is a possibility for optimization.
402  *
403  * For each predecessor p of a Block b there are three cases:
404  *  -1. The predecessor p is a Bad node:  just skip it.  The in array of b shrinks by one.
405  *  -2. The predecessor p is empty.  Remove p.  All predecessors of p are now
406  *      predecessors of b.
407  *  -3. The predecessor p is a block containing useful code.  Just keep p as is.
408  *
409  * For Phi nodes f we have to check the conditions at the Block of f.
410  * For cases 1 and 3 we proceed as for Blocks.  For case 2 we can have two
411  * cases:
412  *  -2a: The old predecessor of the Phi f is a Phi pred_f IN THE BLOCK REMOVED.  In this
413  *      case we proceed as for blocks. We remove pred_f.  All
414  *      predecessors of pred_f now are predecessors of f.
415  *  -2b: The old predecessor of f is NOT in the block removed. It might be a Phi, too.
416  *      We have to replicate f for each predecessor of the removed block. Or, with
417  *      other words, the removed predecessor block has exactly one predecessor.
418  *
419  * Further there is a special case for self referencing blocks:
420  * @verbatim
421  *
422  *    then_b     else_b                              then_b  else_b
423  *       \      /                                      \      /
424  *        \    /                                        |    /
425  *        pred_b                                        |   /
426  *         |   ____                                     |  /  ____
427  *         |  |    |                                    |  | |    |
428  *         |  |    |       === optimized to ===>        \  | |    |
429  *        loop_b   |                                     loop_b   |
430  *         |  |    |                                      |  |    |
431  *         |  |____|                                      |  |____|
432  *         |                                              |
433  * @endverbatim
434  *
435  * If there is a Phi in pred_b, but we remove pred_b, we have to generate a
436  * Phi in loop_b, that has the ins of the Phi in pred_b and a self referencing
437  * backedge.
438  * @@@ It is negotiable whether we should do this ... there might end up a copy
439  * from the Phi in the loop when removing the Phis.
440  */
441 static void optimize_blocks(ir_node *b, void *env) {
442   int i, j, k, n, max_preds, n_preds, p_preds;
443   ir_node *pred, *phi;
444   ir_node **in;
445   defer_ex_phi *defers;
446
447   /* Count the number of predecessor if this block is merged with pred blocks
448      that are empty. */
449   max_preds = 0;
450   for (i = 0, k = get_Block_n_cfgpreds(b); i < k; ++i) {
451     handle_switch_cond(get_Block_cfgpred(b, i));
452     max_preds += test_whether_dispensable(b, i);
453   }
454   in = xmalloc(max_preds * sizeof(*in));
455
456   defers = NEW_ARR_F(defer_ex_phi, 0);
457
458 /*-
459   printf(" working on "); DDMN(b);
460   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
461     pred = get_nodes_block(get_Block_cfgpred(b, i));
462     if (is_Bad(get_Block_cfgpred(b, i))) {
463       printf("  removing Bad %i\n ", i);
464     } else if (get_Block_block_visited(pred) +1
465            < get_irg_block_visited(current_ir_graph)) {
466       printf("  removing pred %i ", i); DDMN(pred);
467     } else { printf("  Nothing to do for "); DDMN(pred); }
468   }
469   * end Debug output -*/
470
471   /*- Fix the Phi nodes of the current block -*/
472   for (phi = get_irn_link(b); phi; ) {
473     assert(get_irn_op(phi) == op_Phi);
474
475     /* Find the new predecessors for the Phi */
476     p_preds = 0;
477     for (i = 0, n = get_Block_n_cfgpreds(b); i < n; ++i) {
478       pred = get_Block_cfgpred_block(b, i);
479
480       if (is_Bad(get_Block_cfgpred(b, i))) {
481         /* case Phi 1: Do nothing */
482       }
483       else if (get_Block_block_visited(pred) + 1
484                  < get_irg_block_visited(current_ir_graph)) {
485         /* case Phi 2: It's an empty block and not yet visited. */
486         ir_node *phi_pred = get_Phi_pred(phi, i);
487
488         for (j = 0, k = get_Block_n_cfgpreds(pred); j < k; j++) {
489           /* because of breaking loops, not all predecessors are Bad-clean,
490            * so we must check this here again */
491           if (! is_Bad(get_Block_cfgpred(pred, j))) {
492             if (get_nodes_block(phi_pred) == pred) {
493               /* case Phi 2a: */
494               assert(get_irn_op(phi_pred) == op_Phi);  /* Block is empty!! */
495
496               in[p_preds++] = get_Phi_pred(phi_pred, j);
497             } else {
498               /* case Phi 2b: */
499               in[p_preds++] = phi_pred;
500             }
501           }
502         }
503
504         /* The Phi_pred node is replaced now if it is a Phi.
505
506            Somehow the removed Phi node can be used legally in loops.
507            Therefore we replace the old phi by the new one.
508            This must be done _AFTER_ all Phis are optimized, or
509            it will fail if two Phis use the same pred_Phi.
510
511            FIXME: Is the following true? We ALWAYS replace it by the new one.
512
513            Further we have to remove the old Phi node by replacing it
514            by Bad.  Else it will remain in the keep alive array of End
515            and cause illegal situations.  So if there is no loop, we should
516            replace it by Bad.
517         */
518         if (get_nodes_block(phi_pred) == pred) {
519           int i;
520           /* remove the Phi as it might be kept alive. Further there
521              might be other users. */
522           for (i = ARR_LEN(defers) - 1; i >= 0; --i)
523             if (defers[i].phi_pred == phi_pred)
524               break;
525
526           if (i < 0) {
527               /* we have a new replacement */
528             defer_ex_phi elem;
529
530             elem.phi_pred = phi_pred;
531             elem.phi      = phi;
532             ARR_APP1(defer_ex_phi, defers, elem);
533           }
534         }
535       } else {
536         /* case Phi 3: */
537         in[p_preds++] = get_Phi_pred(phi, i);
538       }
539     }
540     assert(p_preds <= max_preds);
541
542     /* Fix the node */
543     if (p_preds == 1)
544       /* By removal of Bad ins the Phi might be degenerated. */
545       exchange(phi, in[0]);
546     else
547       set_irn_in(phi, p_preds, in);
548
549     phi = get_irn_link(phi);
550   }
551
552   /* now, exchange all Phis */
553   for (i = ARR_LEN(defers) - 1; i >= 0; --i) {
554     exchange(defers[i].phi_pred, defers[i].phi);
555   }
556   DEL_ARR_F(defers);
557
558   /*- This happens only if merge between loop backedge and single loop entry.
559       See special case above. -*/
560   for (k = 0, n = get_Block_n_cfgpreds(b); k < n; ++k) {
561     pred = get_nodes_block(get_Block_cfgpred(b, k));
562
563     if (get_Block_block_visited(pred) + 1 < get_irg_block_visited(current_ir_graph)) {
564       /* we found a predecessor block at position k that will be removed */
565       for (phi = get_irn_link(pred); phi;) {
566         /*
567          * the previous phase may already changed the phi, and even
568          * removed it at all, so check here if this node is still a phi
569          */
570         if (get_irn_op(phi) == op_Phi) {
571           int q_preds = 0;
572
573           /* move this phi from the predecessor into the block b */
574           set_nodes_block(phi, b);
575
576           /* first, copy all 0..k-1 predecessors */
577           for (i = 0; i < k; i++) {
578             pred = get_nodes_block(get_Block_cfgpred(b, i));
579
580             if (is_Bad(get_Block_cfgpred(b, i))) {
581               /* Do nothing */
582             } else if (get_Block_block_visited(pred) + 1
583                < get_irg_block_visited(current_ir_graph)) {
584               /* It's an empty block and not yet visited. */
585               for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
586                 /* @@@ Hier brauche ich Schleifeninformation!!! Kontrollflusskante
587                    muss Rueckwaertskante sein! (An allen vier in[q_preds] = phi
588                    Anweisungen.) Trotzdem tuts bisher!! */
589                 if (! is_Bad(get_Block_cfgpred(pred, j)))
590                   in[q_preds++] = phi;
591               }
592             } else {
593               in[q_preds++] = phi;
594             }
595           }
596
597           /* now we are at k, copy the phi predecessors */
598           pred = get_nodes_block(get_Block_cfgpred(b, k));
599           for (i = 0; i < get_Phi_n_preds(phi); i++) {
600             if (! is_Bad(get_Block_cfgpred(pred, i)))
601               in[q_preds++] = get_Phi_pred(phi, i);
602           }
603
604           /* and now all the rest */
605           for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
606             pred = get_nodes_block(get_Block_cfgpred(b, i));
607
608             if (is_Bad(get_Block_cfgpred(b, i))) {
609               /* Do nothing */
610             } else if (get_Block_block_visited(pred) +1
611                < get_irg_block_visited(current_ir_graph)) {
612               /* It's an empty block and not yet visited. */
613               for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
614                 if (! is_Bad(get_Block_cfgpred(pred, j)))
615                   in[q_preds++] = phi;
616               }
617             } else {
618               in[q_preds++] = phi;
619             }
620           }
621
622           /* Fix the node */
623           if (q_preds == 1)
624             exchange(phi, in[0]);
625           else
626             set_irn_in(phi, q_preds, in);
627
628           assert(q_preds <= max_preds);
629 //        assert(p_preds == q_preds && "Wrong Phi Fix");
630         }
631         phi = get_irn_link(phi);
632       }
633     }
634   }
635
636   /*- Fix the block -*/
637   n_preds = 0;
638   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
639     pred = get_nodes_block(get_Block_cfgpred(b, i));
640
641     if (is_Bad(get_Block_cfgpred(b, i))) {
642       /* case 1: Do nothing */
643     } else if (get_Block_block_visited(pred) +1
644            < get_irg_block_visited(current_ir_graph)) {
645       /* case 2: It's an empty block and not yet visited. */
646       assert(get_Block_n_cfgpreds(b) > 1);
647       /* Else it should be optimized by equivalent_node. */
648       for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
649         ir_node *pred_block = get_Block_cfgpred(pred, j);
650
651         /* because of breaking loops, not all predecessors are Bad-clean,
652          * so we must check this here again */
653         if (! is_Bad(pred_block))
654           in[n_preds++] = pred_block;
655       }
656       /* Remove block as it might be kept alive. */
657       exchange(pred, b/*new_Bad()*/);
658     } else {
659       /* case 3: */
660       in[n_preds++] = get_Block_cfgpred(b, i);
661     }
662   }
663   assert(n_preds <= max_preds);
664
665   set_irn_in(b, n_preds, in);
666
667   assert(get_irn_link(b) == NULL || (n_preds == p_preds && "Wrong Phi Fix"));
668
669   xfree(in);
670 }
671
672
673 /* Optimizations of the control flow that also require changes of Phi nodes.
674  *
675  * This optimization performs two passes over the graph.
676  *
677  * The first pass collects all Phi nodes in a link list in the block
678  * nodes.  Further it performs simple control flow optimizations.
679  * Finally it marks all blocks that do not contain useful
680  * computations, i.e., these blocks might be removed.
681  *
682  * The second pass performs the optimizations intended by this algorithm.
683  * It walks only over block nodes and adapts these and the Phi nodes in these blocks,
684  * which it finds in a linked list computed by the first pass.
685  *
686  * We use the block_visited flag to mark empty blocks in the first
687  * phase.
688  * @@@ It would be better to add a struct in the link field
689  * that keeps the Phi list and the mark.  Place it on an obstack, as
690  * we will lose blocks and thereby generate memory leaks.
691  */
692 void optimize_cf(ir_graph *irg) {
693   int i, j, n;
694   ir_node **in;
695   ir_node *end = get_irg_end(irg);
696   ir_graph *rem = current_ir_graph;
697   irg_dom_state dom_state = get_irg_dom_state(current_ir_graph);
698   current_ir_graph = irg;
699
700   /* if the graph is not pinned, we cannot determine empty blocks */
701   assert(get_irg_pinned(irg) != op_pin_state_floats &&
702          "Control flow optimization need a pinned graph");
703
704   /* Handle graph state */
705   assert(get_irg_phase_state(irg) != phase_building);
706   set_irg_outs_inconsistent(current_ir_graph);
707   set_irg_extblk_inconsistent(current_ir_graph);
708   set_irg_loopinfo_inconsistent(current_ir_graph);
709   set_irg_doms_inconsistent(current_ir_graph);
710
711   if (dom_state == dom_consistent && get_opt_optimize() && get_opt_unreachable_code()) {
712     ir_node *end;
713
714     /* we have dominance info, we can kill dead block */
715     irg_block_walk_graph(irg, NULL, remove_dead_block_cf, NULL);
716
717     /* fix the keep-alives */
718     end = get_irg_end(irg);
719     for (i = 0, n = get_End_n_keepalives(end); i < n; ++i) {
720       ir_node *ka = get_End_keepalive(end, i);
721
722       if (is_Block(ka)) {
723         /* do NOT keep  dead blocks */
724         if (get_Block_dom_depth(ka) == -1)
725           set_End_keepalive(end, i, new_Bad());
726       }
727       else if (is_Block_dead(get_nodes_block(ka)) ||
728                get_Block_dom_depth(get_nodes_block(ka)) == -1)
729         /* do NOT keep nodes in dead blocks */
730         set_End_keepalive(end, i, new_Bad());
731     }
732   }
733   irg_block_walk_graph(irg, NULL, remove_senseless_conds, NULL);
734
735   /* Use block visited flag to mark non-empty blocks. */
736   inc_irg_block_visited(irg);
737   irg_walk(end, merge_blocks, collect_nodes, NULL);
738
739   /* Optimize the standard code. */
740   irg_block_walk(get_irg_end_block(irg), optimize_blocks, NULL, NULL);
741
742   /* Walk all keep alives, optimize them if block, add to new in-array
743      for end if useful. */
744   n  = get_End_n_keepalives(end);
745   if (n > 0)
746     NEW_ARR_A (ir_node *, in, n);
747   inc_irg_visited(irg);
748
749   /* fix the keep alive */
750   for (i = j = 0; i < n; i++) {
751     ir_node *ka = get_End_keepalive(end, i);
752
753     if (irn_not_visited(ka)) {
754       ir_op *op = get_irn_op(ka);
755
756       if ((op == op_Block) && Block_not_block_visited(ka)) {
757         set_irg_block_visited(irg,  /* Don't walk all the way to Start. */
758               get_irg_block_visited(irg)-1);
759         irg_block_walk(ka, optimize_blocks, NULL, NULL);
760         mark_irn_visited(ka);
761         in[j++] = ka;
762       } else if (op == op_Phi) {
763         mark_irn_visited(ka);
764         if (! is_Block_dead(get_nodes_block(ka)))
765           in[j++] = ka;
766       } else if (is_op_keep(op)) {
767         mark_irn_visited(ka);
768         if (! is_Block_dead(get_nodes_block(ka)))
769           in[j++] = ka;
770       }
771     }
772   }
773   if (j != n)
774     set_End_keepalives(end, j, in);
775
776   /* the verifier doesn't work yet with floating nodes */
777   if (get_irg_pinned(irg) == op_pin_state_pinned) {
778     /* after optimize_cf(), only Bad data flow may remain. */
779     if (irg_vrfy_bads(irg, BAD_DF | BAD_BLOCK | TUPLE)) {
780       dump_ir_block_graph(irg, "-vrfy-cf");
781       dump_ir_graph(irg, "-vrfy-cf");
782       fprintf(stderr, "VRFY_BAD in optimize_cf()\n");
783     }
784   }
785
786   current_ir_graph = rem;
787 }