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