e2a658a43d7b4b8538aea4b4524421a6fe80b72a
[libfirm] / ir / opt / cfopt.c
1 /*
2  * Copyright (C) 1995-2008 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   Control flow optimizations.
23  * @author  Goetz Lindenmaier, Michael Beck, Sebastian Hack
24  * @version $Id$
25  */
26 #include "config.h"
27
28 #include "iroptimize.h"
29
30 #include <assert.h>
31
32 #include "plist.h"
33 #include "xmalloc.h"
34 #include "irnode_t.h"
35 #include "irgraph_t.h"
36 #include "irprog_t.h"
37
38 #include "ircons.h"
39 #include "iropt_t.h"
40 #include "irgwalk.h"
41 #include "irgmod.h"
42 #include "irdump.h"
43 #include "irvrfy.h"
44 #include "iredges.h"
45
46 #include "array_t.h"
47
48 #include "irouts.h"
49 #include "irbackedge_t.h"
50
51 #include "irflag_t.h"
52 #include "firmstat.h"
53 #include "irpass.h"
54
55 #include "iropt_dbg.h"
56
57 /*------------------------------------------------------------------*/
58 /* Control flow optimization.                                       */
59 /*                                                                  */
60 /* Removes Bad control flow predecessors and empty blocks.  A block */
61 /* is empty if it contains only a Jmp node.                         */
62 /* Blocks can only be removed if they are not needed for the        */
63 /* semantics of Phi nodes.                                          */
64 /* Further, we NEVER remove labeled blocks (even if we could move   */
65 /* the label.                                                       */
66 /*------------------------------------------------------------------*/
67
68 #define set_Block_removable(block)      set_Block_mark(block, 1)
69 #define set_Block_non_removable(block)  set_Block_mark(block, 0)
70 #define is_Block_removable(block)       (get_Block_mark(block) != 0)
71
72 /**
73  * Replace binary Conds that jumps twice into the same block
74  * by a simple Jmp.
75  * E.g.
76  * @verbatim
77  *               Cond                     Jmp  Bad
78  *             /       \                   |   /
79  *       ProjX True   ProjX False  ==>     |  /
80  *             \       /                   | /
81  *               Block                    Block
82  * @endverbatim
83  *
84  * Such pattern are the result of if-conversion.
85  *
86  * Note that the simple case that Block has only these two
87  * predecessors are already handled in equivalent_node_Block().
88  */
89 static int remove_senseless_conds(ir_node *bl)
90 {
91         int i, j;
92         int n = get_Block_n_cfgpreds(bl);
93         int changed = 0;
94
95         for (i = 0; i < n; ++i) {
96                 ir_node *pred_i = get_Block_cfgpred(bl, i);
97                 ir_node *cond_i = skip_Proj(pred_i);
98
99                 /* binary Cond */
100                 if (is_Cond(cond_i) && get_irn_mode(get_Cond_selector(cond_i)) == mode_b) {
101
102                         for (j = i + 1; j < n; ++j) {
103                                 ir_node *pred_j = get_Block_cfgpred(bl, j);
104                                 ir_node *cond_j = skip_Proj(pred_j);
105
106                                 if (cond_j == cond_i) {
107                                         ir_node *jmp = new_r_Jmp(get_nodes_block(cond_i));
108                                         set_irn_n(bl, i, jmp);
109                                         set_irn_n(bl, j, new_Bad());
110
111                                         DBG_OPT_IFSIM2(cond_i, jmp);
112                                         changed = 1;
113                                         break;
114                                 }
115                         }
116                 }
117         }
118         return changed;
119 }
120
121 /** An environment for merge_blocks and collect nodes. */
122 typedef struct _merge_env {
123         int changed;    /**< Set if the graph was changed. */
124         int phis_moved; /**< Set if Phi nodes were moved. */
125         plist_t *list;  /**< Helper list for all found Switch Conds. */
126 } merge_env;
127
128 /**
129  * Removes Tuples from Block control flow predecessors.
130  * Optimizes blocks with equivalent_node().  This is tricky,
131  * as we want to avoid nodes that have as block predecessor Bads.
132  * Therefore we also optimize at control flow operations, depending
133  * how we first reach the Block.
134  */
135 static void merge_blocks(ir_node *node, void *ctx)
136 {
137         int i;
138         ir_node *new_block;
139         merge_env *env = ctx;
140
141         /* clear the link field for ALL nodes first */
142         set_irn_link(node, NULL);
143
144         if (is_Block(node)) {
145                 /* Remove Tuples */
146                 for (i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) {
147                         ir_node *pred = get_Block_cfgpred(node, i);
148                         ir_node *skipped = skip_Tuple(pred);
149                         if (pred != skipped) {
150                                 set_Block_cfgpred(node, i, skipped);
151                                 env->changed = 1;
152                         }
153                 }
154
155                 /* see below */
156                 new_block = equivalent_node(node);
157                 if (new_block != node && ! is_Block_dead(new_block)) {
158                         exchange(node, new_block);
159                         env->changed = 1;
160                 }
161
162         } else if (get_opt_optimize() && (get_irn_mode(node) == mode_X)) {
163                 /* We will soon visit a block.  Optimize it before visiting! */
164                 ir_node *b = get_nodes_block(skip_Proj(node));
165
166                 if (!is_Block_dead(b)) {
167                         new_block = equivalent_node(b);
168
169                         while (!irn_visited(b) && !is_Block_dead(new_block) && new_block != b) {
170                                 /* We would have to run gigo() if new is bad, so we
171                                    promote it directly below. Nevertheless, we sometimes reach a block
172                                    the first time through a dataflow node.  In this case we optimized the
173                                    block as such and have to promote the Bad here. */
174                                 assert((get_opt_control_flow_straightening() ||
175                                         get_opt_control_flow_weak_simplification()) &&
176                                         ("strange flag setting"));
177                                 exchange(b, new_block);
178                                 env->changed = 1;
179                                 b = new_block;
180                                 new_block = equivalent_node(b);
181                         }
182
183                         /* normally, we would create a Bad block here, but this must be
184                          * prevented, so just set it's cf to Bad.
185                          */
186                         if (is_Block_dead(new_block)) {
187                                 exchange(node, new_Bad());
188                                 env->changed = 1;
189                         }
190                 }
191         }
192 }
193
194 /**
195  * Block walker removing control flow from dead block by
196  * inspecting dominance info.
197  * Do not replace blocks by Bad.  This optimization shall
198  * ensure, that all Bad control flow predecessors are
199  * removed, and no new other Bads are introduced.
200  * Further removed useless Conds and clear the mark of all blocks.
201  *
202  * Must be run in the post walker.
203  */
204 static void remove_unreachable_blocks_and_conds(ir_node *block, void *env)
205 {
206         int i;
207         int *changed = env;
208
209         /* Check block predecessors and turn control flow into bad.
210            Beware of Tuple, kill them. */
211         for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
212                 ir_node *pred_X  = get_Block_cfgpred(block, i);
213                 ir_node *skipped = skip_Tuple(pred_X);
214
215                 if (! is_Bad(skipped)) {
216                         ir_node *pred_bl = get_nodes_block(skip_Proj(skipped));
217
218                         if (is_Block_dead(pred_bl) || (get_Block_dom_depth(pred_bl) < 0)) {
219                                 set_Block_dead(pred_bl);
220                                 exchange(pred_X, new_Bad());
221                                 *changed = 1;
222                         } else if (skipped != pred_X) {
223                                 set_Block_cfgpred(block, i, skipped);
224                                 *changed = 1;
225                         }
226                 }
227         }
228
229         *changed |= remove_senseless_conds(block);
230
231         /* clear the block mark of all non labeled blocks */
232         if (has_Block_entity(block))
233                 set_Block_non_removable(block);
234         else
235                 set_Block_removable(block);
236 }
237
238 /**
239  * Collects all Phi nodes in link list of Block.
240  * Marks all blocks "non_removable" if they contain a node other
241  * than Jmp (and Proj).
242  * Links all Proj nodes to their predecessors.
243  * Collects all switch-Conds in a list.
244  */
245 static void collect_nodes(ir_node *n, void *ctx)
246 {
247         ir_opcode code = get_irn_opcode(n);
248         merge_env *env = ctx;
249
250         if (code == iro_Block) {
251                 /* mark the block as non-removable if it is labeled */
252                 if (has_Block_entity(n))
253                         set_Block_non_removable(n);
254         } else {
255                 ir_node *b = get_nodes_block(n);
256
257                 if (code == iro_Phi && get_irn_arity(n) > 0) {
258                         /* Collect Phi nodes to compact ins along with block's ins. */
259                         set_irn_link(n, get_irn_link(b));
260                         set_irn_link(b, n);
261                 } else if (code != iro_Jmp && !is_Bad(b)) {  /* Check for non-empty block. */
262                         set_Block_non_removable(b);
263
264                         if (code == iro_Proj) {               /* link Proj nodes */
265                                 ir_node *pred = get_Proj_pred(n);
266
267                                 set_irn_link(n, get_irn_link(pred));
268                                 set_irn_link(pred, n);
269                         } else if (code == iro_Cond) {
270                                 ir_node *sel = get_Cond_selector(n);
271                                 if (mode_is_int(get_irn_mode(sel))) {
272                                         /* found a switch-Cond, collect */
273                                         plist_insert_back(env->list, n);
274                                 }
275                         }
276                 }
277         }
278 }
279
280 /** Returns true if pred is predecessor of block. */
281 static int is_pred_of(ir_node *pred, ir_node *b)
282 {
283         int i;
284
285         for (i = get_Block_n_cfgpreds(b) - 1; i >= 0; --i) {
286                 ir_node *b_pred = get_Block_cfgpred_block(b, i);
287                 if (b_pred == pred)
288                         return 1;
289         }
290         return 0;
291 }
292
293 /** Test whether we can optimize away pred block pos of b.
294  *
295  *  @param  b    A block node.
296  *  @param  pos  The position of the predecessor block to judge about.
297  *
298  *  @returns     The number of predecessors
299  *
300  *  The test is rather tricky.
301  *
302  *  The situation is something like the following:
303  *  @verbatim
304  *                 if-block
305  *                  /   \
306  *              then-b  else-b
307  *                  \   /
308  *                    b
309  *  @endverbatim
310  *
311  *  b merges the control flow of an if-then-else.  We may not remove
312  *  the 'then' _and_ the 'else' block of an 'if' if there is a Phi
313  *  node in b, even if both are empty.  The destruction of this Phi
314  *  requires that a copy is added before the merge.  We have to
315  *  keep one of the case blocks to place the copies in.
316  *
317  *  To perform the test for pos, we must regard predecessors before pos
318  *  as already removed.
319  **/
320 static int test_whether_dispensable(ir_node *b, int pos)
321 {
322         int i, j, n_preds = 1;
323         ir_node *pred = get_Block_cfgpred_block(b, pos);
324
325         /* Bad blocks will be optimized away, so we don't need space for them */
326         if (is_Block_dead(pred))
327                 return 0;
328
329         if (is_Block_removable(pred)) {
330                 if (!get_opt_optimize() || !get_opt_control_flow_strong_simplification()) {
331                         /* Mark block so that is will not be removed: optimization is turned off. */
332                         set_Block_non_removable(pred);
333                         return 1;
334                 }
335
336                 /* Seems to be empty. At least we detected this in collect_nodes. */
337                 if (get_irn_link(b) == NULL) {
338                         /* There are no Phi nodes ==> all predecessors are dispensable. */
339                         n_preds = get_Block_n_cfgpreds(pred);
340                 } else {
341                         /* b's pred blocks and pred's pred blocks must be pairwise disjunct.
342                            Handle all pred blocks with preds < pos as if they were already removed. */
343                         for (i = 0; i < pos; i++) {
344                                 ir_node *b_pred = get_Block_cfgpred_block(b, i);
345                                 if (! is_Block_dead(b_pred) && is_Block_removable(b_pred)) {
346                                         for (j = get_Block_n_cfgpreds(b_pred) - 1; j >= 0; --j) {
347                                                 ir_node *b_pred_pred = get_Block_cfgpred_block(b_pred, j);
348                                                 if (is_pred_of(b_pred_pred, pred))
349                                                         goto non_dispensable;
350                                         }
351                                 } else {
352                                         if (is_pred_of(b_pred, pred))
353                                                 goto non_dispensable;
354                                 }
355                         }
356                         for (i = pos +1; i < get_Block_n_cfgpreds(b); i++) {
357                                 ir_node *b_pred = get_Block_cfgpred_block(b, i);
358                                 if (is_pred_of(b_pred, pred))
359                                         goto non_dispensable;
360                         }
361                         /* if we get here, the block is dispensable */
362                         n_preds = get_Block_n_cfgpreds(pred);
363                 }
364         }
365
366         return n_preds;
367
368 non_dispensable:
369         set_Block_non_removable(pred);
370         return 1;
371 }
372
373 /**
374  * This method removed Bad cf predecessors from Blocks and Phis, and removes
375  * empty blocks.  A block is empty if it only contains Phi and Jmp nodes.
376  *
377  * We first adapt Phi nodes, then Block nodes, as we need the old ins
378  * of the Block to adapt the Phi nodes.  We do this by computing new
379  * in arrays, and then replacing the old ones.  So far we compute new in arrays
380  * for all nodes, not regarding whether there is a possibility for optimization.
381  *
382  * For each predecessor p of a Block b there are three cases:
383  *  -1. The predecessor p is a Bad node:  just skip it.  The in array of b shrinks by one.
384  *  -2. The predecessor p is empty.  Remove p.  All predecessors of p are now
385  *      predecessors of b.
386  *  -3. The predecessor p is a block containing useful code.  Just keep p as is.
387  *
388  * For Phi nodes f we have to check the conditions at the Block of f.
389  * For cases 1 and 3 we proceed as for Blocks.  For case 2 we can have two
390  * cases:
391  *  -2a: The old predecessor of the Phi f is a Phi pred_f IN THE BLOCK REMOVED.  In this
392  *      case we proceed as for blocks. We remove pred_f.  All
393  *      predecessors of pred_f now are predecessors of f.
394  *  -2b: The old predecessor of f is NOT in the block removed. It might be a Phi, too.
395  *      We have to replicate f for each predecessor of the removed block. Or, with
396  *      other words, the removed predecessor block has exactly one predecessor.
397  *
398  * Further there is a special case for self referencing blocks:
399  * @verbatim
400  *
401  *    then_b     else_b                              then_b  else_b
402  *       \      /                                      \      /
403  *        \    /                                        |    /
404  *        pred_b                                        |   /
405  *         |   ____                                     |  /  ____
406  *         |  |    |                                    |  | |    |
407  *         |  |    |       === optimized to ===>        \  | |    |
408  *        loop_b   |                                     loop_b   |
409  *         |  |    |                                      |  |    |
410  *         |  |____|                                      |  |____|
411  *         |                                              |
412  * @endverbatim
413  *
414  * If there is a Phi in pred_b, but we remove pred_b, we have to generate a
415  * Phi in loop_b, that has the ins of the Phi in pred_b and a self referencing
416  * backedge.
417  * @@@ It is negotiable whether we should do this ... there might end up a copy
418  * from the Phi in the loop when removing the Phis.
419  */
420 static void optimize_blocks(ir_node *b, void *ctx)
421 {
422         int i, j, k, n, max_preds, n_preds, p_preds = -1;
423         ir_node *pred, *phi, *next;
424         ir_node **in;
425         merge_env *env = ctx;
426
427         /* Count the number of predecessor if this block is merged with pred blocks
428            that are empty. */
429         max_preds = 0;
430         for (i = 0, k = get_Block_n_cfgpreds(b); i < k; ++i) {
431                 max_preds += test_whether_dispensable(b, i);
432         }
433         in = XMALLOCN(ir_node*, max_preds);
434
435         /*- Fix the Phi nodes of the current block -*/
436         for (phi = get_irn_link(b); phi != NULL; phi = next) {
437                 assert(is_Phi(phi));
438                 next = get_irn_link(phi);
439
440                 /* Find the new predecessors for the Phi */
441                 p_preds = 0;
442                 for (i = 0, n = get_Block_n_cfgpreds(b); i < n; ++i) {
443                         pred = get_Block_cfgpred_block(b, i);
444
445                         if (is_Block_dead(pred)) {
446                                 /* case Phi 1: Do nothing */
447                         } else if (is_Block_removable(pred) && !Block_block_visited(pred)) {
448                                 /* case Phi 2: It's an empty block and not yet visited. */
449                                 ir_node *phi_pred = get_Phi_pred(phi, i);
450
451                                 for (j = 0, k = get_Block_n_cfgpreds(pred); j < k; j++) {
452                                         /* because of breaking loops, not all predecessors are Bad-clean,
453                                          * so we must check this here again */
454                                         if (! is_Bad(get_Block_cfgpred(pred, j))) {
455                                                 if (get_nodes_block(phi_pred) == pred) {
456                                                         /* case Phi 2a: */
457                                                         assert(is_Phi(phi_pred));  /* Block is empty!! */
458
459                                                         in[p_preds++] = get_Phi_pred(phi_pred, j);
460                                                 } else {
461                                                         /* case Phi 2b: */
462                                                         in[p_preds++] = phi_pred;
463                                                 }
464                                         }
465                                 }
466                         } else {
467                                 /* case Phi 3: */
468                                 in[p_preds++] = get_Phi_pred(phi, i);
469                         }
470                 }
471                 assert(p_preds <= max_preds);
472
473                 /* Fix the node */
474                 if (p_preds == 1)
475                         /* By removal of Bad ins the Phi might be degenerated. */
476                         exchange(phi, in[0]);
477                 else
478                         set_irn_in(phi, p_preds, in);
479                 env->changed = 1;
480         }
481
482         /*- This happens only if merge between loop backedge and single loop entry.
483             Moreover, it is only needed if predb is the direct dominator of b, else there can be no uses
484             of the Phi's in predb ... -*/
485         for (k = 0, n = get_Block_n_cfgpreds(b); k < n; ++k) {
486                 ir_node *predb = get_nodes_block(get_Block_cfgpred(b, k));
487
488                 if (is_Block_removable(predb) && !Block_block_visited(predb)) {
489                         ir_node *next_phi;
490
491                         /* we found a predecessor block at position k that will be removed */
492                         for (phi = get_irn_link(predb); phi; phi = next_phi) {
493                                 int q_preds = 0;
494                                 next_phi = get_irn_link(phi);
495
496                                 assert(is_Phi(phi));
497
498                                 if (get_Block_idom(b) != predb) {
499                                         /* predb is not the dominator. There can't be uses of pred's Phi nodes, kill them .*/
500                                         exchange(phi, new_Bad());
501                                 } else {
502                                         /* predb is the direct dominator of b. There might be uses of the Phi nodes from
503                                            predb in further block, so move this phi from the predecessor into the block b */
504                                         set_nodes_block(phi, b);
505                                         set_irn_link(phi, get_irn_link(b));
506                                         set_irn_link(b, phi);
507                                         env->phis_moved = 1;
508
509                                         /* first, copy all 0..k-1 predecessors */
510                                         for (i = 0; i < k; i++) {
511                                                 pred = get_Block_cfgpred_block(b, i);
512
513                                                 if (is_Block_dead(pred)) {
514                                                         /* Do nothing */
515                                                 } else if (is_Block_removable(pred) && !Block_block_visited(pred)) {
516                                                         /* It's an empty block and not yet visited. */
517                                                         for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
518                                                                 if (! is_Bad(get_Block_cfgpred(pred, j)))
519                                                                         in[q_preds++] = phi;
520                                                         }
521                                                 } else {
522                                                         in[q_preds++] = phi;
523                                                 }
524                                         }
525
526                                         /* now we are at k, copy the phi predecessors */
527                                         pred = get_nodes_block(get_Block_cfgpred(b, k));
528                                         for (i = 0; i < get_Phi_n_preds(phi); i++) {
529                                                 if (! is_Bad(get_Block_cfgpred(pred, i)))
530                                                         in[q_preds++] = get_Phi_pred(phi, i);
531                                         }
532
533                                         /* and now all the rest */
534                                         for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
535                                                 pred = get_Block_cfgpred_block(b, i);
536
537                                                 if (is_Block_dead(pred)) {
538                                                         /* Do nothing */
539                                                 } else if (is_Block_removable(pred) && !Block_block_visited(pred)) {
540                                                         /* It's an empty block and not yet visited. */
541                                                         for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
542                                                                 if (! is_Bad(get_Block_cfgpred(pred, j)))
543                                                                         in[q_preds++] = phi;
544                                                         }
545                                                 } else {
546                                                         in[q_preds++] = phi;
547                                                 }
548                                         }
549
550                                         /* Fix the node */
551                                         if (q_preds == 1)
552                                                 exchange(phi, in[0]);
553                                         else
554                                                 set_irn_in(phi, q_preds, in);
555                                         env->changed = 1;
556
557                                         assert(q_preds <= max_preds);
558                                         // assert(p_preds == q_preds && "Wrong Phi Fix");
559                                 }
560                         }
561                 }
562         }
563
564         /*- Fix the block -*/
565         n_preds = 0;
566         for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
567                 pred = get_Block_cfgpred_block(b, i);
568
569                 if (is_Block_dead(pred)) {
570                         /* case 1: Do nothing */
571                 } else if (is_Block_removable(pred) && !Block_block_visited(pred)) {
572                         /* case 2: It's an empty block and not yet visited. */
573                         assert(get_Block_n_cfgpreds(b) > 1 || has_Block_entity(b));
574                         /* Else it should be optimized by equivalent_node. */
575                         for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
576                                 ir_node *pred_X = get_Block_cfgpred(pred, j);
577
578                                 /* because of breaking loops, not all predecessors are Bad-clean,
579                                  * so we must check this here again */
580                                 if (! is_Bad(pred_X))
581                                         in[n_preds++] = pred_X;
582                         }
583                         /* Remove block as it might be kept alive. */
584                         exchange(pred, b/*new_Bad()*/);
585                 } else {
586                         /* case 3: */
587                         in[n_preds++] = get_Block_cfgpred(b, i);
588                 }
589         }
590         assert(n_preds <= max_preds);
591
592         set_irn_in(b, n_preds, in);
593         env->changed = 1;
594
595         assert(get_irn_link(b) == NULL || p_preds == -1 || (n_preds == p_preds && "Wrong Phi Fix"));
596         xfree(in);
597 }
598
599 /**
600  * Block walker: optimize all blocks using the default optimizations.
601  * This removes Blocks that with only a Jmp predecessor.
602  */
603 static void remove_simple_blocks(ir_node *block, void *ctx)
604 {
605         ir_node *new_blk = equivalent_node(block);
606         merge_env *env = ctx;
607
608         if (new_blk != block) {
609                 exchange(block, new_blk);
610                 env->changed = 1;
611         }
612 }
613
614 /**
615  * Handle pre-optimized table switch Cond's.
616  * During iropt, all Projs from a switch-Cond are already removed except
617  * the defProj and maybe the taken one.
618  * The defProj cannot be removed WITHOUT looking backwards, so we do this here.
619  *
620  * @param cond the switch-Cond
621  *
622  * @return non-zero if a switch-Cond was optimized
623  *
624  * Expects all Proj's linked to the cond node
625  */
626 static int handle_switch_cond(ir_node *cond)
627 {
628         ir_node *sel = get_Cond_selector(cond);
629
630         ir_node *proj1 = get_irn_link(cond);
631         ir_node *proj2 = get_irn_link(proj1);
632         ir_node *jmp, *blk;
633
634         blk = get_nodes_block(cond);
635
636         if (proj2 == NULL) {
637                 /* this Cond has only one Proj: must be the defProj */
638                 assert(get_Cond_default_proj(cond) == get_Proj_proj(proj1));
639                 /* convert it into a Jmp */
640                 jmp = new_r_Jmp(blk);
641                 exchange(proj1, jmp);
642                 return 1;
643         } else if (get_irn_link(proj2) == NULL) {
644                 /* We have two Proj's here. Check if the Cond has
645                    a constant argument */
646                 tarval *tv = value_of(sel);
647
648                 if (tv != tarval_bad) {
649                         /* we have a constant switch */
650                         long num     = get_tarval_long(tv);
651                         long def_num = get_Cond_default_proj(cond);
652
653                         if (def_num == get_Proj_proj(proj1)) {
654                                 /* first one is the defProj */
655                                 if (num == get_Proj_proj(proj2)) {
656                                         jmp = new_r_Jmp(blk);
657                                         exchange(proj2, jmp);
658                                         exchange(proj1, new_Bad());
659                                         return 1;
660                                 }
661                         } else if (def_num == get_Proj_proj(proj2)) {
662                                 /* second one is the defProj */
663                                 if (num == get_Proj_proj(proj1)) {
664                                         jmp = new_r_Jmp(blk);
665                                         exchange(proj1, jmp);
666                                         exchange(proj2, new_Bad());
667                                         return 1;
668                                 }
669                         } else {
670                                 /* neither: strange, Cond was not optimized so far */
671                                 if (num == get_Proj_proj(proj1)) {
672                                         jmp = new_r_Jmp(blk);
673                                         exchange(proj1, jmp);
674                                         exchange(proj2, new_Bad());
675                                         return 1;
676                                 } else if (num == get_Proj_proj(proj2)) {
677                                         jmp = new_r_Jmp(blk);
678                                         exchange(proj2, jmp);
679                                         exchange(proj1, new_Bad());
680                                         return 1;
681                                 }
682                         }
683                 }
684         }
685         return 0;
686 }
687
688 /* Optimizations of the control flow that also require changes of Phi nodes.
689  *
690  * This optimization performs two passes over the graph.
691  *
692  * The first pass collects all Phi nodes in a link list in the block
693  * nodes.  Further it performs simple control flow optimizations.
694  * Finally it marks all blocks that do not contain useful
695  * computations, i.e., these blocks might be removed.
696  *
697  * The second pass performs the optimizations intended by this algorithm.
698  * It walks only over block nodes and adapts these and the Phi nodes in these blocks,
699  * which it finds in a linked list computed by the first pass.
700  *
701  * We use the mark flag to mark removable blocks in the first
702  * phase.
703  */
704 void optimize_cf(ir_graph *irg)
705 {
706         int i, j, n, changed;
707         ir_node **in = NULL;
708         ir_node *cond, *end = get_irg_end(irg);
709         ir_graph *rem = current_ir_graph;
710         plist_element_t *el;
711         merge_env env;
712
713         assert(get_irg_phase_state(irg) != phase_building);
714
715         /* if the graph is not pinned, we cannot determine empty blocks */
716         assert(get_irg_pinned(irg) != op_pin_state_floats &&
717                "Control flow optimization need a pinned graph");
718
719         current_ir_graph = irg;
720
721         /* FIXME: control flow opt destroys block edges. So edges are deactivated here. Fix the edges! */
722         edges_deactivate(irg);
723
724         /* we use the mark flag to mark removable blocks */
725         ir_reserve_resources(irg, IR_RESOURCE_BLOCK_MARK);
726 restart:
727         env.changed    = 0;
728         env.phis_moved = 0;
729
730         /* ALWAYS kill unreachable control flow. Backend cannot handle it anyway.
731            Use dominator info to kill blocks. Also optimize useless Conds. */
732         assure_doms(irg);
733         irg_block_walk_graph(irg, NULL, remove_unreachable_blocks_and_conds, &env.changed);
734
735         /* fix the keep-alives */
736         changed = 0;
737         for (i = 0, n = get_End_n_keepalives(end); i < n; ++i) {
738                 ir_node *ka = get_End_keepalive(end, i);
739
740                 if (is_Block(ka)) {
741                         /* do NOT keep dead blocks */
742                         if (is_Block_dead(ka) || get_Block_dom_depth(ka) < 0) {
743                                 set_End_keepalive(end, i, new_Bad());
744                                 changed = 1;
745                         }
746                 } else {
747                         ir_node *block = get_nodes_block(ka);
748
749                         if (is_Bad(block) || is_Block_dead(block) || get_Block_dom_depth(block) < 0) {
750                                 /* do NOT keep nodes in dead blocks */
751                                 set_End_keepalive(end, i, new_Bad());
752                                 changed = 1;
753                         }
754                 }
755         }
756         env.changed |= changed;
757
758         ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
759
760         env.list = plist_new();
761         irg_walk(end, merge_blocks, collect_nodes, &env);
762
763         ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
764
765         if (env.changed) {
766                 /* Handle graph state if was changed. */
767                 set_irg_outs_inconsistent(irg);
768                 set_irg_doms_inconsistent(irg);
769                 set_irg_extblk_inconsistent(irg);
770                 set_irg_loopinfo_inconsistent(irg);
771                 set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
772                 env.changed = 0;
773         }
774
775         /* handle all collected switch-Conds */
776         foreach_plist(env.list, el) {
777                 cond = plist_element_get_value(el);
778                 env.changed |= handle_switch_cond(cond);
779         }
780         plist_free(env.list);
781
782         if (env.changed) {
783                 /* The Cond optimization might generate unreachable code, so restart if
784                    it happens. */
785                 goto restart;
786         }
787
788         /* Optimize the standard code. */
789         env.changed = 0;
790         assure_doms(irg);
791         irg_block_walk_graph(irg, optimize_blocks, remove_simple_blocks, &env);
792
793         /* in rare cases a node may be kept alive more than once, use the visited flag to detect this */
794         ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
795         inc_irg_visited(irg);
796
797         /* fix the keep-alives again */
798         changed = 0;
799         for (i = 0, n = get_End_n_keepalives(end); i < n; ++i) {
800                 ir_node *ka = get_End_keepalive(end, i);
801
802                 if (is_Block(ka)) {
803                         /* do NOT keep dead blocks */
804                         if (is_Block_dead(ka) || get_Block_dom_depth(ka) < 0) {
805                                 set_End_keepalive(end, i, new_Bad());
806                                 changed = 1;
807                         }
808                 } else {
809                         ir_node *block = get_nodes_block(ka);
810
811                         if (is_Bad(block) || is_Block_dead(block) || get_Block_dom_depth(block) < 0) {
812                                 /* do NOT keep nodes in dead blocks */
813                                 set_End_keepalive(end, i, new_Bad());
814                                 changed = 1;
815                         }
816                 }
817         }
818         env.changed |= changed;
819
820         remove_End_Bads_and_doublets(end);
821
822
823         ir_free_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_IRN_VISITED);
824
825         if (env.phis_moved) {
826                 /* Bad: when we moved Phi's, we might produce dead Phi nodes
827                    that are kept-alive.
828                    Some other phases cannot copy with this, so will them.
829                  */
830                 n = get_End_n_keepalives(end);
831                 if (n > 0) {
832                         NEW_ARR_A(ir_node *, in, n);
833                         if (env.changed) {
834                                 /* Handle graph state if was changed. */
835                                 set_irg_outs_inconsistent(irg);
836                         }
837                         assure_irg_outs(irg);
838
839                         for (i = j = 0; i < n; ++i) {
840                                 ir_node *ka = get_End_keepalive(end, i);
841
842                                 if (is_Phi(ka)) {
843                                         int k;
844
845                                         for (k = get_irn_n_outs(ka) - 1; k >= 0; --k) {
846                                                 ir_node *user = get_irn_out(ka, k);
847
848                                                 if (user != ka && user != end) {
849                                                         /* Is it a real user or just a self loop ? */
850                                                         break;
851                                                 }
852                                         }
853                                         if (k >= 0)
854                                                 in[j++] = ka;
855                                 } else
856                                         in[j++] = ka;
857                         }
858                         if (j != n) {
859                                 set_End_keepalives(end, j, in);
860                                 env.changed = 1;
861                         }
862                 }
863         }
864
865         if (env.changed) {
866                 /* Handle graph state if was changed. */
867                 set_irg_outs_inconsistent(irg);
868                 set_irg_doms_inconsistent(irg);
869                 set_irg_extblk_inconsistent(irg);
870                 set_irg_loopinfo_inconsistent(irg);
871                 set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
872         }
873
874
875         /* the verifier doesn't work yet with floating nodes */
876         if (get_irg_pinned(irg) == op_pin_state_pinned) {
877                 /* after optimize_cf(), only Bad data flow may remain. */
878                 if (irg_vrfy_bads(irg, BAD_DF | BAD_BLOCK | TUPLE)) {
879                         dump_ir_block_graph(irg, "-vrfy-cf");
880                         dump_ir_graph(irg, "-vrfy-cf");
881                         fprintf(stderr, "VRFY_BAD in optimize_cf()\n");
882                 }
883         }
884
885         current_ir_graph = rem;
886 }
887
888 /* Creates an ir_graph pass for optimize_cf. */
889 ir_graph_pass_t *optimize_cf_pass(const char *name)
890 {
891         return def_graph_pass(name ? name : "optimize_cf", optimize_cf);
892 }  /* optimize_cf_pass */