optimize polymorphic field accesses
[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 #include <assert.h>
17
18 #include "xmalloc.h"
19 #include "irnode_t.h"
20 #include "irgraph_t.h"
21 #include "irprog_t.h"
22
23 #include "ircons.h"
24 #include "iropt_t.h"
25 #include "irgwalk.h"
26 #include "irgmod.h"
27 #include "irdump.h"
28 #include "irvrfy.h"
29
30 #include "array.h"
31
32 #include "irouts.h"
33 #include "irbackedge_t.h"
34
35 #include "irflag_t.h"
36 #include "firmstat.h"
37
38 #include "cfopt.h"
39
40 /*------------------------------------------------------------------*/
41 /* Control flow optimization.                                       */
42 /*                                                                  */
43 /* Removes Bad control flow predecessors and empty blocks.  A block */
44 /* is empty if it contains only a Jmp node.                         */
45 /* Blocks can only be removed if they are not needed for the        */
46 /* semantics of Phi nodes.                                          */
47 /*------------------------------------------------------------------*/
48
49
50 static void remove_senseless_conds(ir_node *bl, void *data)
51 {
52         int i, j;
53         int n = get_irn_arity(bl);
54
55         assert(is_Block(bl));
56
57         for(i = 0; i < n; ++i) {
58                 ir_node *pred_i = get_irn_n(bl, i);
59                 ir_node *cond_i = skip_Proj(pred_i);
60
61                 for(j = i + 1; j < n; ++j) {
62                         ir_node *pred_j = get_irn_n(bl, j);
63                         ir_node *cond_j = skip_Proj(pred_j);
64
65                         if(cond_j == cond_i
66                                         && get_irn_opcode(cond_i) == iro_Cond
67                                         && get_irn_mode(get_Cond_selector(cond_i)) == mode_b) {
68
69                                 ir_node *jmp = new_r_Jmp(current_ir_graph, get_nodes_block(cond_i));
70                                 set_irn_n(bl, i, jmp);
71                                 set_irn_n(bl, j, new_Bad());
72
73                                 break;
74                         }
75                 }
76         }
77 }
78
79
80 /**
81  * Removes Tuples from Block control flow predecessors.
82  * Optimizes blocks with equivalent_node().  This is tricky,
83  * as we want to avoid nodes that have as block predecessor Bads.
84  * Therefore we also optimize at control flow operations, depending
85  * how we first reach the Block.
86  */
87 static void merge_blocks(ir_node *n, void *env) {
88   int i;
89   ir_node *new_block;
90
91   /* clear the link field for ALL nodes first */
92   set_irn_link(n, NULL);
93
94   if (get_irn_op(n) == op_Block) {
95     /* Remove Tuples */
96     for (i = 0; i < get_Block_n_cfgpreds(n); i++) {
97       /* GL @@@ : is this possible? if (get_opt_normalize()) -- added, all tests go through.
98          A different order of optimizations might cause problems. */
99       if (get_opt_normalize())
100         set_Block_cfgpred(n, i, skip_Tuple(get_Block_cfgpred(n, i)));
101     }
102
103     /* see below */
104     new_block = equivalent_node(n);
105     if (new_block != n && ! is_Bad(new_block))
106       exchange (n, new_block);
107
108   } else if (get_opt_optimize() && (get_irn_mode(n) == mode_X)) {
109     /* We will soon visit a block.  Optimize it before visiting! */
110     ir_node *b = get_nodes_block(skip_Proj(n));
111
112     if (!is_Bad(b)) {
113       new_block = equivalent_node(b);
114
115       while (irn_not_visited(b) && (!is_Bad(new_block)) && (new_block != b)) {
116         /* We would have to run gigo if new is bad, so we
117            promote it directly below. Nevertheless, we sometimes reach a block
118            the first time through a dataflow node.  In this case we optimized the
119            block as such and have to promote the Bad here. */
120         assert((get_opt_control_flow_straightening() ||
121                 get_opt_control_flow_weak_simplification()) &&
122                ("strange flag setting"));
123         exchange (b, new_block);
124         b = new_block;
125         new_block = equivalent_node(b);
126       }
127
128       /* normally, we would create a Bad block here, but this must be
129        * prevented, so just set it's cf to Bad.
130        */
131       if (is_Bad(new_block))
132         exchange(n, new_Bad());
133     }
134   }
135 }
136
137 /**
138  * Remove cf from dead block by inspecting dominance info
139  * Do not replace blocks by Bad.  This optimization shall
140  * ensure, that all Bad cfg preds are removed, and no new
141  * other Bads are introduced.
142  *
143  * Must be run in the post walker.
144  */
145 static void remove_dead_block_cf(ir_node *block, void *env)
146 {
147   int i, n;
148
149   /* check block predecessors and turn control flow into bad */
150   for (i = 0, n = get_Block_n_cfgpreds(block); i < n; ++i) {
151     ir_node *pred_X = get_Block_cfgpred(block, i);
152
153     if (! is_Bad(pred_X)) {
154       ir_node *pred_bl = get_nodes_block(skip_Proj(pred_X));
155
156       if (is_Bad(pred_bl) || (get_Block_dom_depth(pred_bl) == -1))
157         exchange (pred_X, new_Bad());
158     }
159   }
160 }
161
162 /**
163  * Collects all Phi nodes in link list of Block.
164  * Marks all blocks "block_visited" if they contain a node other
165  * than Jmp.
166  * Replaces n by Bad if n is unreachable control flow. We do that
167  * in the post walker, so we catch all blocks.
168  */
169 static void collect_nodes(ir_node *n, void *env) {
170   if (is_no_Block(n)) {
171     ir_node *b = get_nodes_block(n);
172
173     if ((get_irn_op(n) == op_Phi)) {
174       /* Collect Phi nodes to compact ins along with block's ins. */
175       set_irn_link(n, get_irn_link(b));
176       set_irn_link(b, n);
177     }
178     else if ((get_irn_op(n) != op_Jmp) && !is_Bad(b)) {  /* Check for non empty block. */
179       mark_Block_block_visited(b);
180     }
181   }
182 }
183
184 /** Returns true if pred is predecessor of block. */
185 static int is_pred_of(ir_node *pred, ir_node *b) {
186   int i, n;
187
188   for (i = 0, n = get_Block_n_cfgpreds(b); i < n; ++i) {
189     ir_node *b_pred = get_nodes_block(get_Block_cfgpred(b, i));
190     if (b_pred == pred) return 1;
191   }
192   return 0;
193 }
194
195
196 /** Test wether we can optimize away pred block pos of b.
197  *
198  *  @param  b    A block node.
199  *  @param  pos  The position of the predecessor block to judge about.
200  *
201  *  @returns     The number of predecessors
202  *
203  *  The test is rather tricky.
204  *
205  *  The situation is something like the following:
206  *
207  *                 if-block
208  *                  /   \
209  *              then-b  else-b
210  *                  \   /
211  *                    b
212  *
213  *     b merges the control flow of an if-then-else.  We may not remove
214  *     the 'then' _and_ the 'else' block of an 'if' if there is a Phi
215  *     node in b, even if both are empty.  The destruction of this Phi
216  *     requires that a copy is added before the merge.  We have to
217  *     keep one of the case blocks to place the copies in.
218  *
219  *     To perform the test for pos, we must regard preds before pos
220  *     as already removed.
221  **/
222 static int test_whether_dispensable(ir_node *b, int pos) {
223   int i, j, n_preds = 1;
224   int dispensable = 1;
225   ir_node *cfop = get_Block_cfgpred(b, pos);
226   ir_node *pred = get_nodes_block(cfop);
227
228   /* Bad blocks will be optimized away, so we don't need space for them */
229   if (is_Bad(pred))
230     return 0;
231
232   if (get_Block_block_visited(pred) + 1
233       < get_irg_block_visited(current_ir_graph)) {
234
235     if (!get_opt_optimize() || !get_opt_control_flow_strong_simplification()) {
236       /* Mark block so that is will not be removed: optimization is turned off. */
237       set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
238       return 1;
239     }
240
241     /* Seems to be empty. At least we detected this in collect_nodes. */
242     if (!get_irn_link(b)) {
243       /* There are no Phi nodes ==> all predecessors are dispensable. */
244       n_preds = get_Block_n_cfgpreds(pred);
245     } else {
246       /* b's pred blocks and pred's pred blocks must be pairwise disjunct.
247          Work preds < pos as if they were already removed. */
248       for (i = 0; i < pos; i++) {
249         ir_node *b_pred = get_nodes_block(get_Block_cfgpred(b, i));
250         if (get_Block_block_visited(b_pred) + 1
251             < get_irg_block_visited(current_ir_graph)) {
252           for (j = 0; j < get_Block_n_cfgpreds(b_pred); j++) {
253             ir_node *b_pred_pred = get_nodes_block(get_Block_cfgpred(b_pred, j));
254             if (is_pred_of(b_pred_pred, pred)) dispensable = 0;
255           }
256         } else {
257           if (is_pred_of(b_pred, pred)) dispensable = 0;
258         }
259       }
260       for (i = pos +1; i < get_Block_n_cfgpreds(b); i++) {
261         ir_node *b_pred = get_nodes_block(get_Block_cfgpred(b, i));
262         if (is_pred_of(b_pred, pred)) dispensable = 0;
263       }
264       if (!dispensable) {
265         set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
266         n_preds = 1;
267       } else {
268         n_preds = get_Block_n_cfgpreds(pred);
269       }
270     }
271   }
272
273   return n_preds;
274 }
275
276
277 /**
278  * This method removed Bad cf preds from Blocks and Phis, and removes
279  * empty blocks.  A block is empty if it only contains Phi and Jmp nodes.
280  *
281  * We first adapt Phi nodes, then Block nodes, as we need the old ins
282  * of the Block to adapt the Phi nodes.  We do this by computing new
283  * in arrays, and then replacing the old ones.  So far we compute new in arrays
284  * for all nodes, not regarding whether there is a possibility for optimization.
285  *
286  * For each predecessor p of a Block b there are three cases:
287  *  1. The predecessor p is a Bad node:  just skip it.  The in array of b shrinks by one.
288  *  2. The predecessor p is empty.  Remove p.  All predecessors of p are now
289  *     predecessors of b.
290  *  3. The predecessor p is a block containing useful code.  Just keep p as is.
291  *
292  * For Phi nodes f we have to check the conditions at the Block of f.
293  * For cases 1 and 3 we proceed as for Blocks.  For case 2 we can have two
294  * cases:
295  *  2a: The old precessor of the Phi f is a Phi pred_f IN THE BLOCK REMOVED.  In this
296  *      case we proceed as for blocks. We remove pred_f.  All
297  *      predecessors of pred_f now are predecessors of f.
298  *  2b: The old predecessor of f is NOT in the block removed. It might be a Phi, too.
299  *      We have to replicate f for each predecessor of the removed block. Or, with
300  *      other words, the removed predecessor block has exactly one predecessor.
301  *
302  * Further there is a special case for self referencing blocks:
303  *
304  *    then_b     else_b                              then_b  else_b
305  *       \      /                                      \      /
306  *        \    /                                        |    /
307  *        pred_b                                        |   /
308  *         |   ____                                     |  /
309  *         |  |    |                                    |  | |    |
310  *         |  |    |       === optimized to ===>        \  | |    |
311  *        loop_b   |                                     loop_b   |
312  *         |  |    |                                      |  |    |
313  *         |  |____|                                      |  |____|
314  *         |                                              |
315  *
316  * If there is a Phi in pred_b, but we remove pred_b, we have to generate a
317  * Phi in loop_b, that has the ins of the Phi in pred_b and a self referencing
318  * backedge.
319  * @@@ It is negotiable whether we should do this ... there might end up a copy
320  * from the Phi in the loop when removing the Phis.
321  */
322 static void optimize_blocks(ir_node *b, void *env) {
323   int i, j, k, n, max_preds, n_preds, p_preds;
324   ir_node *pred, *phi;
325   ir_node **in;
326
327   /* Count the number of predecessor if this block is merged with pred blocks
328      that are empty. */
329   max_preds = 0;
330   for (i = 0, k = get_Block_n_cfgpreds(b); i < k; ++i) {
331     max_preds += test_whether_dispensable(b, i);
332   }
333   in = xmalloc(max_preds * sizeof(*in));
334
335 /*-
336   printf(" working on "); DDMN(b);
337   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
338     pred = get_nodes_block(get_Block_cfgpred(b, i));
339     if (is_Bad(get_Block_cfgpred(b, i))) {
340       printf("  removing Bad %i\n ", i);
341     } else if (get_Block_block_visited(pred) +1
342            < get_irg_block_visited(current_ir_graph)) {
343       printf("  removing pred %i ", i); DDMN(pred);
344     } else { printf("  Nothing to do for "); DDMN(pred); }
345   }
346   * end Debug output -*/
347
348   /*- Fix the Phi nodes of the current block -*/
349   for (phi = get_irn_link(b); phi; ) {
350     assert(get_irn_op(phi) == op_Phi);
351
352     /* Find the new predecessors for the Phi */
353     p_preds = 0;
354     for (i = 0, n = get_Block_n_cfgpreds(b); i < n; ++i) {
355       pred = get_nodes_block(get_Block_cfgpred(b, i));
356
357       if (is_Bad(get_Block_cfgpred(b, i))) {
358         /* case Phi 1: Do nothing */
359       }
360       else if (get_Block_block_visited(pred) + 1
361                  < get_irg_block_visited(current_ir_graph)) {
362         /* case Phi 2: It's an empty block and not yet visited. */
363         ir_node *phi_pred = get_Phi_pred(phi, i);
364
365         for (j = 0, k = get_Block_n_cfgpreds(pred); j < k; j++) {
366           /* because of breaking loops, not all predecessors are Bad-clean,
367            * so we must check this here again */
368           if (! is_Bad(get_Block_cfgpred(pred, j))) {
369             if (get_nodes_block(phi_pred) == pred) {
370               /* case Phi 2a: */
371               assert(get_irn_op(phi_pred) == op_Phi);  /* Block is empty!! */
372
373               in[p_preds++] = get_Phi_pred(phi_pred, j);
374             } else {
375               /* case Phi 2b: */
376               in[p_preds++] = phi_pred;
377             }
378           }
379         }
380
381         /* The Phi_pred node is replaced now if it is a Phi.
382
383            Somehow the removed Phi node can be used legally in loops.
384            Therefore we replace the old phi by the new one.
385
386            Further we have to remove the old Phi node by replacing it
387            by Bad.  Else it will remain in the keepalive array of End
388            and cause illegal situations.  So if there is no loop, we should
389            replace it by Bad.
390         */
391         if (get_nodes_block(phi_pred) == pred) {
392           /* remove the Phi as it might be kept alive. Further there
393              might be other users. */
394           exchange(phi_pred, phi);  /* geht, ist aber doch semantisch falsch! Warum?? */
395         }
396       } else {
397         /* case Phi 3: */
398         in[p_preds++] = get_Phi_pred(phi, i);
399       }
400     }
401     assert(p_preds <= max_preds);
402
403     /* Fix the node */
404     if (p_preds == 1)
405       /* By removal of Bad ins the Phi might be degenerated. */
406       exchange(phi, in[0]);
407     else
408       set_irn_in(phi, p_preds, in);
409
410     phi = get_irn_link(phi);
411   }
412
413   /*- This happens only if merge between loop backedge and single loop entry.
414       See special case above. -*/
415   for (k = 0, n = get_Block_n_cfgpreds(b); k < n; ++k) {
416     pred = get_nodes_block(get_Block_cfgpred(b, k));
417
418     if (get_Block_block_visited(pred) + 1 < get_irg_block_visited(current_ir_graph)) {
419       /* we found a predecessor block at position k that will be removed */
420       for (phi = get_irn_link(pred); phi;) {
421         /*
422          * the previous phase may already changed the phi, and even
423          * removed it at all, so check here if this node is still a phi
424          */
425         if (get_irn_op(phi) == op_Phi) {
426           int q_preds = 0;
427
428           /* move this phi from the predecessor into the block b */
429           set_nodes_block(phi, b);
430
431           /* first, copy all 0..k-1 predecessors */
432           for (i = 0; i < k; i++) {
433             pred = get_nodes_block(get_Block_cfgpred(b, i));
434
435             if (is_Bad(get_Block_cfgpred(b, i))) {
436               /* Do nothing */
437             } else if (get_Block_block_visited(pred) + 1
438                < get_irg_block_visited(current_ir_graph)) {
439               /* It's an empty block and not yet visited. */
440               for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
441                 /* @@@ Hier brauche ich Schleifeninformation!!! Kontrollflusskante
442                    muss Rueckwaertskante sein! (An allen vier in[q_preds] = phi
443                    Anweisungen.) Trotzdem tuts bisher!! */
444                 if (! is_Bad(get_Block_cfgpred(pred, j)))
445                   in[q_preds++] = phi;
446               }
447             } else {
448               in[q_preds++] = phi;
449             }
450           }
451
452           /* now we are at k, copy the phi predecessors */
453           pred = get_nodes_block(get_Block_cfgpred(b, k));
454           for (i = 0; i < get_Phi_n_preds(phi); i++) {
455             if (! is_Bad(get_Block_cfgpred(pred, i)))
456               in[q_preds++] = get_Phi_pred(phi, i);
457           }
458
459           /* and now all the rest */
460           for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
461             pred = get_nodes_block(get_Block_cfgpred(b, i));
462
463             if (is_Bad(get_Block_cfgpred(b, i))) {
464               /* Do nothing */
465             } else if (get_Block_block_visited(pred) +1
466                < get_irg_block_visited(current_ir_graph)) {
467               /* It's an empty block and not yet visited. */
468               for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
469                 if (! is_Bad(get_Block_cfgpred(pred, j)))
470                   in[q_preds++] = phi;
471               }
472             } else {
473               in[q_preds++] = phi;
474             }
475           }
476
477           /* Fix the node */
478           if (q_preds == 1)
479             exchange(phi, in[0]);
480           else
481             set_irn_in(phi, q_preds, in);
482
483           assert(q_preds <= max_preds);
484 //        assert(p_preds == q_preds && "Wrong Phi Fix");
485         }
486         phi = get_irn_link(phi);
487       }
488     }
489   }
490
491   /*- Fix the block -*/
492   n_preds = 0;
493   for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
494     pred = get_nodes_block(get_Block_cfgpred(b, i));
495
496     if (is_Bad(get_Block_cfgpred(b, i))) {
497       /* case 1: Do nothing */
498     } else if (get_Block_block_visited(pred) +1
499            < get_irg_block_visited(current_ir_graph)) {
500       /* case 2: It's an empty block and not yet visited. */
501       assert(get_Block_n_cfgpreds(b) > 1);
502                         /* Else it should be optimized by equivalent_node. */
503       for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
504         ir_node *pred_block = get_Block_cfgpred(pred, j);
505
506         /* because of breaking loops, not all predecessors are Bad-clean,
507          * so we must check this here again */
508         if (! is_Bad(pred_block))
509           in[n_preds++] = pred_block;
510       }
511       /* Remove block as it might be kept alive. */
512       exchange(pred, b/*new_Bad()*/);
513     } else {
514       /* case 3: */
515       in[n_preds++] = get_Block_cfgpred(b, i);
516     }
517   }
518   assert(n_preds <= max_preds);
519
520   set_irn_in(b, n_preds, in);
521
522   assert(get_irn_link(b) == NULL || (n_preds == p_preds && "Wrong Phi Fix"));
523
524   xfree(in);
525 }
526
527
528 /* Optimizations of the control flow that also require changes of Phi nodes.
529  *
530  * This optimization performs two passes over the graph.
531  *
532  * The first pass collects all Phi nodes in a link list in the block
533  * nodes.  Further it performs simple control flow optimizations.
534  * Finally it marks all blocks that do not contain useful
535  * computations, i.e., these blocks might be removed.
536  *
537  * The second pass performs the optimizations intended by this algorithm.
538  * It walks only over block nodes and adapts these and the Phi nodes in these blocks,
539  * which it finds in a linked list computed by the first pass.
540  *
541  * We use the block_visited flag to mark empty blocks in the first
542  * phase.
543  * @@@ It would be better to add a struct in the link field
544  * that keeps the Phi list and the mark.  Place it on an obstack, as
545  * we will lose blocks and thereby generate mem leaks.
546  */
547 void optimize_cf(ir_graph *irg) {
548   int i, n;
549   ir_node **in;
550   ir_node *end = get_irg_end(irg);
551   ir_graph *rem = current_ir_graph;
552   irg_dom_state dom_state = get_irg_dom_state(current_ir_graph);
553   current_ir_graph = irg;
554
555   /* Handle graph state */
556   assert(get_irg_phase_state(irg) != phase_building);
557   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
558     set_irg_outs_inconsistent(current_ir_graph);
559   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
560     set_irg_dom_inconsistent(current_ir_graph);
561
562   if (dom_state == dom_consistent && get_opt_optimize() && get_opt_unreachable_code()) {
563     ir_node *end = get_irg_end(irg);
564
565     /* we have dominace info, we can kill dead block */
566     irg_block_walk_graph(irg, NULL, remove_dead_block_cf, NULL);
567
568     /* fix the keep-alives */
569     for (i = 0, n = get_End_n_keepalives(end); i < n; ++i) {
570       ir_node *ka = get_End_keepalive(end, i);
571
572       if (is_Block(ka) && (get_Block_dom_depth(ka) == -1))
573         set_End_keepalive(end, i, new_Bad());
574       if (is_Phi(ka) && (get_Block_dom_depth(get_nodes_block(ka)) == -1))
575         set_End_keepalive(end, i, new_Bad());
576     }
577   }
578
579   irg_block_walk_graph(current_ir_graph, NULL, remove_senseless_conds, NULL);
580   /* Use block visited flag to mark non-empty blocks. */
581   inc_irg_block_visited(irg);
582   irg_walk(end, merge_blocks, collect_nodes, NULL);
583
584   /* Optimize the standard code. */
585   irg_block_walk(get_irg_end_block(irg), optimize_blocks, NULL, NULL);
586
587   /* Walk all keep alives, optimize them if block, add to new in-array
588      for end if useful. */
589   in = NEW_ARR_F (ir_node *, 1);
590   in[0] = get_nodes_block(end);
591   inc_irg_visited(current_ir_graph);
592
593   for (i = 0; i < get_End_n_keepalives(end); i++) {
594     ir_node *ka = get_End_keepalive(end, i);
595
596     if (irn_not_visited(ka)) {
597       if ((get_irn_op(ka) == op_Block) && Block_not_block_visited(ka)) {
598         set_irg_block_visited(current_ir_graph,  /* Don't walk all the way to Start. */
599               get_irg_block_visited(current_ir_graph)-1);
600         irg_block_walk(ka, optimize_blocks, NULL, NULL);
601         mark_irn_visited(ka);
602         ARR_APP1 (ir_node *, in, ka);
603       } else if (get_irn_op(ka) == op_Phi) {
604         mark_irn_visited(ka);
605         ARR_APP1 (ir_node *, in, ka);
606       }
607     }
608   }
609   /* DEL_ARR_F(end->in);   GL @@@ tut nicht ! */
610   end->in = in;
611
612
613   /* the verifyer doesn't work yet with floating nodes */
614   if (get_irg_pinned(irg) == op_pin_state_pinned) {
615     /* after optimize_cf(), only Bad data flow may remain. */
616     if (irg_vrfy_bads(irg, BAD_DF | BAD_BLOCK | TUPLE)) {
617       dump_ir_block_graph(irg, "-vrfy-cf");
618       dump_ir_graph(irg, "-vrfy-cf");
619       fprintf(stderr, "VRFY_BAD in optimize_cf()\n");
620     }
621   }
622
623   current_ir_graph = rem;
624 }