OSDN Git Service

2005-03-06 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-phiopt.c
1 /* Optimization of PHI nodes by converting them into straightline code.
2    Copyright (C) 2004 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5    
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10    
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15    
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "errors.h"
26 #include "ggc.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "flags.h"
30 #include "tm_p.h"
31 #include "basic-block.h"
32 #include "timevar.h"
33 #include "diagnostic.h"
34 #include "tree-flow.h"
35 #include "tree-pass.h"
36 #include "tree-dump.h"
37 #include "langhooks.h"
38
39 static void tree_ssa_phiopt (void);
40 static bool conditional_replacement (basic_block, basic_block, basic_block,
41                                      edge, edge, tree, tree, tree);
42 static bool value_replacement (basic_block, basic_block, basic_block,
43                                edge, edge, tree, tree, tree);
44 static bool abs_replacement (basic_block, basic_block, basic_block,
45                              edge, edge, tree, tree, tree);
46 static void replace_phi_edge_with_variable (basic_block, basic_block, edge,
47                                             tree, tree);
48
49 /* This pass eliminates PHI nodes which can be trivially implemented as
50    an assignment from a conditional expression.  i.e. if we have something
51    like:
52
53      bb0:
54       if (cond) goto bb2; else goto bb1;
55      bb1:
56      bb2:
57       x = PHI (0 (bb1), 1 (bb0)
58
59    We can rewrite that as:
60     
61      bb0:
62      bb1:
63      bb2:
64       x = cond;
65
66    bb1 will become unreachable and bb0 and bb2 will almost always
67    be merged into a single block.  This occurs often due to gimplification
68     of conditionals. 
69    
70    Also done is the following optimization:
71
72      bb0:
73       if (a != b) goto bb2; else goto bb1;
74      bb1:
75      bb2:
76       x = PHI (a (bb1), b (bb0))
77
78    We can rewrite that as:
79
80      bb0:
81      bb1:
82      bb2:
83       x = b;
84
85    This can sometimes occur as a result of other optimizations.  A
86    similar transformation is done by the ifcvt RTL optimizer. 
87
88    This pass also eliminates PHI nodes which are really absolute 
89    values.  i.e. if we have something like:
90
91      bb0:
92       if (a >= 0) goto bb2; else goto bb1;
93      bb1:
94       x = -a;
95      bb2:
96       x = PHI (x (bb1), a (bb0));
97
98    We can rewrite that as:
99
100      bb0:
101      bb1:
102      bb2:
103       x = ABS_EXPR< a >;
104
105    bb1 will become unreachable and bb0 and bb2 will almost always be merged
106    into a single block.  Similar transformations are done by the ifcvt
107    RTL optimizer.  */ 
108
109 static void
110 tree_ssa_phiopt (void)
111 {
112   basic_block bb;
113   bool removed_phis = false;
114
115   /* Search every basic block for COND_EXPR we may be able to optimize in reverse
116      order so we can find more.  */
117   FOR_EACH_BB_REVERSE (bb)
118     {
119       tree cond_expr;
120       tree phi;
121       basic_block bb1, bb2;
122       edge e1, e2;
123       
124       cond_expr = last_stmt (bb);
125       /* Check to see if the last statement is a COND_EXPR */
126       if (!cond_expr
127           || TREE_CODE (cond_expr) != COND_EXPR)
128         continue;
129       
130       e1 = EDGE_SUCC (bb, 0);
131       bb1 = e1->dest;
132       e2 = EDGE_SUCC (bb, 1);
133       bb2 = e2->dest;
134       
135       /* We cannot do the optimization on abnormal edges.  */
136       if ((e1->flags & EDGE_ABNORMAL) != 0
137           || (e2->flags & EDGE_ABNORMAL) != 0)
138        continue;
139       
140       /* If either bb1's succ or bb2 or bb2's succ is non NULL.  */
141       if (EDGE_COUNT (bb1->succs) < 1
142           || bb2 == NULL
143           || EDGE_COUNT (bb2->succs) < 1)
144         continue;
145       
146       /* Find the bb which is the fall through to the other.  */
147       if (EDGE_SUCC (bb1, 0)->dest == bb2)
148         ;
149       else if (EDGE_SUCC (bb2, 0)->dest == bb1)
150         {
151           basic_block bb_tmp = bb1;
152           edge e_tmp = e1;
153           bb1 = bb2;
154           bb2 = bb_tmp;
155           e1 = e2;
156           e2 = e_tmp;
157         }
158       else
159         continue;
160       
161       e1 = EDGE_SUCC (bb1, 0);
162       
163       /* Make sure that bb1 is just a fall through.  */
164       if (EDGE_COUNT (bb1->succs) > 1
165           || (e1->flags & EDGE_FALLTHRU) == 0)
166         continue;
167         
168       /* Also make that bb1 only have one pred and it is bb. */
169       if (EDGE_COUNT (bb1->preds) > 1
170           || EDGE_PRED (bb1, 0)->src != bb)
171         continue;
172       
173       phi = phi_nodes (bb2);
174
175       /* Check to make sure that there is only one PHI node.
176          TODO: we could do it with more than one iff the other PHI nodes
177          have the same elements for these two edges.  */
178       if (phi && PHI_CHAIN (phi) == NULL)
179         {
180           tree arg0 = NULL, arg1 = NULL;
181           int i;
182           
183           arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
184           arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
185                   
186           /* We know something is wrong if we cannot find the edges in the PHI
187              node.  */
188           gcc_assert (arg0 != NULL && arg1 != NULL);
189             
190           /* Do the replacement of conditional if it can be done.  */
191             if (conditional_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1)
192                 || value_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1)
193                 || abs_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
194               {
195                 /* We have done the replacement so we need to rebuild the
196                    cfg when this pass is complete.  */
197                 removed_phis = true;
198               }
199         }
200     }
201 }
202
203 /* Return TRUE if block BB has no executable statements, otherwise return
204    FALSE.  */
205 bool
206 empty_block_p (basic_block bb)
207 {
208   block_stmt_iterator bsi;
209
210   /* BB must have no executable statements.  */
211   bsi = bsi_start (bb);
212   while (!bsi_end_p (bsi)
213           && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
214               || IS_EMPTY_STMT (bsi_stmt (bsi))))
215     bsi_next (&bsi);
216   
217   if (!bsi_end_p (bsi))
218     return false;
219
220   return true;
221 }
222
223 /* Replace PHI node element whoes edge is E in block BB with variable NEW.
224    Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
225    is known to have two edges, one of which must reach BB).  */
226
227 static void
228 replace_phi_edge_with_variable (basic_block cond_block, basic_block bb,
229                                 edge e, tree phi, tree new)
230 {
231   basic_block block_to_remove;
232   int i;
233   block_stmt_iterator bsi;
234
235   /* Change the PHI argument to new. */
236   PHI_ARG_DEF_TREE (phi, e->dest_idx) = new;
237
238   /* Remove the empty basic block.  */
239   if (EDGE_SUCC (cond_block, 0)->dest == bb)
240     {
241       EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
242       EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
243
244       block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
245     }
246   else
247     {
248       EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
249       EDGE_SUCC (cond_block, 1)->flags
250         &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
251
252       block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
253     }
254   delete_basic_block (block_to_remove);
255   
256   /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
257   bsi = bsi_last (cond_block);
258   bsi_remove (&bsi);
259   
260   if (dump_file && (dump_flags & TDF_DETAILS))
261     fprintf (dump_file,
262               "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
263               cond_block->index,
264               bb->index);
265 }
266
267 /*  The function conditional_replacement does the main work of doing the
268     conditional replacement.  Return true if the replacement is done.
269     Otherwise return false.
270     BB is the basic block where the replacement is going to be done on.  ARG0
271     is argument 0 from PHI.  Likewise for ARG1.  */
272
273 static bool
274 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
275                          basic_block phi_bb, edge e0, edge e1, tree phi,
276                          tree arg0, tree arg1)
277 {
278   tree result;
279   tree old_result = NULL;
280   tree new, cond;
281   block_stmt_iterator bsi;
282   edge true_edge, false_edge;
283   tree new_var = NULL;
284   tree new_var1;
285
286   /* The PHI arguments have the constants 0 and 1, then convert
287      it to the conditional.  */
288   if ((integer_zerop (arg0) && integer_onep (arg1))
289       || (integer_zerop (arg1) && integer_onep (arg0)))
290     ;
291   else
292     return false;
293   
294   if (!empty_block_p (middle_bb))
295     return false;
296                                                                                 
297   /* If the condition is not a naked SSA_NAME and its type does not
298      match the type of the result, then we have to create a new
299      variable to optimize this case as it would likely create
300      non-gimple code when the condition was converted to the
301      result's type.  */
302   cond = COND_EXPR_COND (last_stmt (cond_bb));
303   result = PHI_RESULT (phi);
304   if (TREE_CODE (cond) != SSA_NAME
305       && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
306     {
307       new_var = make_rename_temp (TREE_TYPE (cond), NULL);
308       old_result = cond;
309       cond = new_var;
310     }
311   
312   /* If the condition was a naked SSA_NAME and the type is not the
313      same as the type of the result, then convert the type of the
314      condition.  */
315   if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
316     cond = fold_convert (TREE_TYPE (result), cond);
317   
318   /* We need to know which is the true edge and which is the false
319      edge so that we know when to invert the condition below.  */
320   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
321       
322   /* Insert our new statement at the end of condtional block before the
323      COND_EXPR.  */
324   bsi = bsi_last (cond_bb);
325   bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
326   
327   if (old_result)
328     {
329       tree new1;
330       if (!COMPARISON_CLASS_P (old_result))
331         return false;
332       
333       new1 = build (TREE_CODE (old_result), TREE_TYPE (old_result),
334                     TREE_OPERAND (old_result, 0),
335                     TREE_OPERAND (old_result, 1));
336       
337       new1 = build (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
338       bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
339     }
340     
341   new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
342   
343   
344   /* At this point we know we have a COND_EXPR with two successors.
345      One successor is BB, the other successor is an empty block which
346      falls through into BB.
347   
348      There is a single PHI node at the join point (BB) and its arguments
349      are constants (0, 1).
350   
351      So, given the condition COND, and the two PHI arguments, we can
352      rewrite this PHI into non-branching code: 
353   
354        dest = (COND) or dest = COND'
355   
356      We use the condition as-is if the argument associated with the
357      true edge has the value one or the argument associated with the
358      false edge as the value zero.  Note that those conditions are not
359      the same since only one of the outgoing edges from the COND_EXPR
360      will directly reach BB and thus be associated with an argument.  */
361   if ((e0 == true_edge && integer_onep (arg0))
362       || (e0 == false_edge && integer_zerop (arg0))
363       || (e1 == true_edge && integer_onep (arg1))
364       || (e1 == false_edge && integer_zerop (arg1)))
365     {
366       new = build (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
367     }
368   else
369     {
370       tree cond1 = invert_truthvalue (cond);
371       
372       cond = cond1;
373       /* If what we get back is a conditional expression, there is no
374           way that it can be gimple.  */
375       if (TREE_CODE (cond) == COND_EXPR)
376         {
377           release_ssa_name (new_var1);
378           return false; 
379         }
380
381       /* If what we get back is not gimple try to create it as gimple by
382          using a temporary variable.  */
383       if (is_gimple_cast (cond)
384           && !is_gimple_val (TREE_OPERAND (cond, 0)))
385         {
386           tree temp = TREE_OPERAND (cond, 0);
387           tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
388           new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
389           bsi_insert_after (&bsi, new, BSI_NEW_STMT);
390           cond = fold_convert (TREE_TYPE (result), new_var_1);
391         }
392       
393       if (TREE_CODE (cond) == TRUTH_NOT_EXPR
394           &&  !is_gimple_val (TREE_OPERAND (cond, 0)))
395         {
396           release_ssa_name (new_var1);
397           return false;
398         }
399
400       new = build (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
401     }
402   
403   bsi_insert_after (&bsi, new, BSI_NEW_STMT);
404   
405   SSA_NAME_DEF_STMT (new_var1) = new;
406   
407   replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, new_var1);
408
409   /* Note that we optimized this PHI.  */
410   return true;
411 }
412
413 /*  The function value_replacement does the main work of doing the value
414     replacement.  Return true if the replacement is done.  Otherwise return
415     false.
416     BB is the basic block where the replacement is going to be done on.  ARG0
417     is argument 0 from the PHI.  Likewise for ARG1.  */
418
419 static bool
420 value_replacement (basic_block cond_bb, basic_block middle_bb,
421                    basic_block phi_bb, edge e0, edge e1, tree phi,
422                    tree arg0, tree arg1)
423 {
424   tree result;
425   tree cond;
426   edge true_edge, false_edge;
427
428   /* If the type says honor signed zeros we cannot do this
429      optimization.  */
430   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
431     return false;
432
433   if (!empty_block_p (middle_bb))
434     return false;
435
436   cond = COND_EXPR_COND (last_stmt (cond_bb));
437   result = PHI_RESULT (phi);
438
439   /* This transformation is only valid for equality comparisons.  */
440   if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
441     return false;
442
443   /* We need to know which is the true edge and which is the false
444       edge so that we know if have abs or negative abs.  */
445   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
446
447   /* At this point we know we have a COND_EXPR with two successors.
448      One successor is BB, the other successor is an empty block which
449      falls through into BB.
450
451      The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
452
453      There is a single PHI node at the join point (BB) with two arguments.
454
455      We now need to verify that the two arguments in the PHI node match
456      the two arguments to the equality comparison.  */
457   
458   if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
459        && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
460       || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
461           && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
462     {
463       edge e;
464       tree arg;
465
466       /* For NE_EXPR, we want to build an assignment result = arg where
467          arg is the PHI argument associated with the true edge.  For
468          EQ_EXPR we want the PHI argument associated with the false edge.  */
469       e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
470
471       /* Unfortunately, E may not reach BB (it may instead have gone to
472          OTHER_BLOCK).  If that is the case, then we want the single outgoing
473          edge from OTHER_BLOCK which reaches BB and represents the desired
474          path from COND_BLOCK.  */
475       if (e->dest == middle_bb)
476         e = EDGE_SUCC (e->dest, 0);
477
478       /* Now we know the incoming edge to BB that has the argument for the
479          RHS of our new assignment statement.  */
480       if (e0 == e)
481         arg = arg0;
482       else
483         arg = arg1;
484
485       replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, arg);
486
487       /* Note that we optimized this PHI.  */
488       return true;
489     }
490   return false;
491 }
492
493 /*  The function absolute_replacement does the main work of doing the absolute
494     replacement.  Return true if the replacement is done.  Otherwise return
495     false.
496     bb is the basic block where the replacement is going to be done on.  arg0
497     is argument 0 from the phi.  Likewise for arg1.   */
498
499 static bool
500 abs_replacement (basic_block cond_bb, basic_block middle_bb,
501                  basic_block phi_bb, edge e0 ATTRIBUTE_UNUSED, edge e1, tree phi,
502                  tree arg0, tree arg1)
503 {
504   tree result;
505   tree new, cond;
506   block_stmt_iterator bsi;
507   edge true_edge, false_edge;
508   tree assign = NULL;
509   edge e;
510   tree rhs = NULL, lhs = NULL;
511   bool negate;
512   enum tree_code cond_code;
513
514   /* If the type says honor signed zeros we cannot do this
515      optimization.  */
516   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
517     return false;
518
519   /* OTHER_BLOCK must have only one executable statement which must have the
520      form arg0 = -arg1 or arg1 = -arg0.  */
521   bsi = bsi_start (middle_bb);
522   while (!bsi_end_p (bsi))
523     {
524       tree stmt = bsi_stmt (bsi);
525
526       /* Empty statements and labels are uninteresting.  */
527       if (TREE_CODE (stmt) == LABEL_EXPR
528           || IS_EMPTY_STMT (stmt))
529         {
530           bsi_next (&bsi);
531           continue;
532         }
533
534       /* If we found the assignment, but it was not the only executable
535          statement in OTHER_BLOCK, then we can not optimize.  */
536       if (assign)
537         return false;
538
539       /* If we got here, then we have found the first executable statement
540          in OTHER_BLOCK.  If it is anything other than arg = -arg1 or
541          arg1 = -arg0, then we can not optimize.  */
542       if (TREE_CODE (stmt) == MODIFY_EXPR)
543         {
544           lhs = TREE_OPERAND (stmt, 0);
545           rhs = TREE_OPERAND (stmt, 1);
546
547           if (TREE_CODE (rhs) == NEGATE_EXPR)
548             {
549               rhs = TREE_OPERAND (rhs, 0);
550
551               /* The assignment has to be arg0 = -arg1 or arg1 = -arg0.  */
552               if ((lhs == arg0 && rhs == arg1)
553                   || (lhs == arg1 && rhs == arg0))
554                 {
555                   assign = stmt;
556                   bsi_next (&bsi);
557                 }
558               else
559                 return false;
560             }
561           else
562             return false;
563         }
564       else
565         return false;
566     }
567
568   /* If we did not find the proper negation assignment, then we can not
569      optimize.  */
570   if (assign == NULL)
571     return false;
572
573   cond = COND_EXPR_COND (last_stmt (cond_bb));
574   result = PHI_RESULT (phi);
575
576   /* Only relationals comparing arg[01] against zero are interesting.  */
577   cond_code = TREE_CODE (cond);
578   if (cond_code != GT_EXPR && cond_code != GE_EXPR
579       && cond_code != LT_EXPR && cond_code != LE_EXPR)
580     return false;
581
582   /* Make sure the conditional is arg[01] OP y.  */
583   if (TREE_OPERAND (cond, 0) != rhs)
584     return false;
585
586   if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
587                ? real_zerop (TREE_OPERAND (cond, 1))
588                : integer_zerop (TREE_OPERAND (cond, 1)))
589     ;
590   else
591     return false;
592
593   /* We need to know which is the true edge and which is the false
594      edge so that we know if have abs or negative abs.  */
595   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
596
597   /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
598      will need to negate the result.  Similarly for LT_EXPR/LE_EXPR if
599      the false edge goes to OTHER_BLOCK.  */
600   if (cond_code == GT_EXPR || cond_code == GE_EXPR)
601     e = true_edge;
602   else
603     e = false_edge;
604   
605   if (e->dest == middle_bb)
606     negate = true;
607   else
608     negate = false;
609     
610   result = duplicate_ssa_name (result, NULL);
611   
612   if (negate)
613     lhs = make_rename_temp (TREE_TYPE (result), NULL);
614   else
615     lhs = result;
616
617   /* Build the modify expression with abs expression.  */
618   new = build (MODIFY_EXPR, TREE_TYPE (lhs),
619                lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
620
621   bsi = bsi_last (cond_bb);
622   bsi_insert_before (&bsi, new, BSI_NEW_STMT);
623
624   if (negate)
625     {
626
627       /* Get the right BSI.  We want to insert after the recently 
628          added ABS_EXPR statement (which we know is the first statement
629          in the block.  */
630       new = build (MODIFY_EXPR, TREE_TYPE (result),
631                    result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
632
633       bsi_insert_after (&bsi, new, BSI_NEW_STMT);
634       
635     }
636     
637   SSA_NAME_DEF_STMT (result) = new;
638   replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, result);
639
640   /* Note that we optimized this PHI.  */
641   return true;
642 }
643
644
645 /* Always do these optimizations if we have SSA
646    trees to work on.  */                                                
647 static bool
648 gate_phiopt (void)
649 {
650   return 1;
651 }
652                                                                                                 
653 struct tree_opt_pass pass_phiopt =
654 {
655   "phiopt",                             /* name */
656   gate_phiopt,                          /* gate */
657   tree_ssa_phiopt,                      /* execute */
658   NULL,                                 /* sub */
659   NULL,                                 /* next */
660   0,                                    /* static_pass_number */
661   TV_TREE_PHIOPT,                       /* tv_id */
662   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
663   0,                                    /* properties_provided */
664   0,                                    /* properties_destroyed */
665   0,                                    /* todo_flags_start */
666   TODO_cleanup_cfg | TODO_dump_func | TODO_ggc_collect  /* todo_flags_finish */
667     | TODO_verify_ssa | TODO_rename_vars
668     | TODO_verify_flow | TODO_verify_stmts,
669   0                                     /* letter */
670 };
671                                                                                                 
672