OSDN Git Service

* tree-ssa-phiopt.c (tree_ssa_phiopt,
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-phiopt.c
1 /* Optimization of PHI nodes by converting them into straightline code.
2    Copyright (C) 2004, 2005 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
116      in reverse 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
182           arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
183           arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
184
185           /* We know something is wrong if we cannot find the edges in the PHI
186              node.  */
187           gcc_assert (arg0 != NULL && arg1 != NULL);
188
189           /* Do the replacement of conditional if it can be done.  */
190           if (conditional_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1)
191               || value_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1)
192               || abs_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
193             {
194               /* We have done the replacement so we need to rebuild the
195                  cfg when this pass is complete.  */
196               removed_phis = true;
197             }
198         }
199     }
200 }
201
202 /* Return TRUE if block BB has no executable statements, otherwise return
203    FALSE.  */
204 bool
205 empty_block_p (basic_block bb)
206 {
207   block_stmt_iterator bsi;
208
209   /* BB must have no executable statements.  */
210   bsi = bsi_start (bb);
211   while (!bsi_end_p (bsi)
212           && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
213               || IS_EMPTY_STMT (bsi_stmt (bsi))))
214     bsi_next (&bsi);
215
216   if (!bsi_end_p (bsi))
217     return false;
218
219   return true;
220 }
221
222 /* Replace PHI node element whoes edge is E in block BB with variable NEW.
223    Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
224    is known to have two edges, one of which must reach BB).  */
225
226 static void
227 replace_phi_edge_with_variable (basic_block cond_block, basic_block bb,
228                                 edge e, tree phi, tree new)
229 {
230   basic_block block_to_remove;
231   block_stmt_iterator bsi;
232
233   /* Change the PHI argument to new.  */
234   PHI_ARG_DEF_TREE (phi, e->dest_idx) = new;
235
236   /* Remove the empty basic block.  */
237   if (EDGE_SUCC (cond_block, 0)->dest == bb)
238     {
239       EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
240       EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
241
242       block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
243     }
244   else
245     {
246       EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
247       EDGE_SUCC (cond_block, 1)->flags
248         &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
249
250       block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
251     }
252   delete_basic_block (block_to_remove);
253
254   /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
255   bsi = bsi_last (cond_block);
256   bsi_remove (&bsi);
257
258   if (dump_file && (dump_flags & TDF_DETAILS))
259     fprintf (dump_file,
260               "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
261               cond_block->index,
262               bb->index);
263 }
264
265 /*  The function conditional_replacement does the main work of doing the
266     conditional replacement.  Return true if the replacement is done.
267     Otherwise return false.
268     BB is the basic block where the replacement is going to be done on.  ARG0
269     is argument 0 from PHI.  Likewise for ARG1.  */
270
271 static bool
272 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
273                          basic_block phi_bb, edge e0, edge e1, tree phi,
274                          tree arg0, tree arg1)
275 {
276   tree result;
277   tree old_result = NULL;
278   tree new, cond;
279   block_stmt_iterator bsi;
280   edge true_edge, false_edge;
281   tree new_var = NULL;
282   tree new_var1;
283
284   /* The PHI arguments have the constants 0 and 1, then convert
285      it to the conditional.  */
286   if ((integer_zerop (arg0) && integer_onep (arg1))
287       || (integer_zerop (arg1) && integer_onep (arg0)))
288     ;
289   else
290     return false;
291
292   if (!empty_block_p (middle_bb))
293     return false;
294
295   /* If the condition is not a naked SSA_NAME and its type does not
296      match the type of the result, then we have to create a new
297      variable to optimize this case as it would likely create
298      non-gimple code when the condition was converted to the
299      result's type.  */
300   cond = COND_EXPR_COND (last_stmt (cond_bb));
301   result = PHI_RESULT (phi);
302   if (TREE_CODE (cond) != SSA_NAME
303       && !lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
304     {
305       new_var = make_rename_temp (TREE_TYPE (cond), NULL);
306       old_result = cond;
307       cond = new_var;
308     }
309
310   /* If the condition was a naked SSA_NAME and the type is not the
311      same as the type of the result, then convert the type of the
312      condition.  */
313   if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
314     cond = fold_convert (TREE_TYPE (result), cond);
315
316   /* We need to know which is the true edge and which is the false
317      edge so that we know when to invert the condition below.  */
318   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
319
320   /* Insert our new statement at the end of condtional block before the
321      COND_EXPR.  */
322   bsi = bsi_last (cond_bb);
323   bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
324
325   if (old_result)
326     {
327       tree new1;
328       if (!COMPARISON_CLASS_P (old_result))
329         return false;
330
331       new1 = build (TREE_CODE (old_result), TREE_TYPE (old_result),
332                     TREE_OPERAND (old_result, 0),
333                     TREE_OPERAND (old_result, 1));
334
335       new1 = build (MODIFY_EXPR, TREE_TYPE (old_result), new_var, new1);
336       bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
337     }
338
339   new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
340
341
342   /* At this point we know we have a COND_EXPR with two successors.
343      One successor is BB, the other successor is an empty block which
344      falls through into BB.
345
346      There is a single PHI node at the join point (BB) and its arguments
347      are constants (0, 1).
348
349      So, given the condition COND, and the two PHI arguments, we can
350      rewrite this PHI into non-branching code:
351
352        dest = (COND) or dest = COND'
353
354      We use the condition as-is if the argument associated with the
355      true edge has the value one or the argument associated with the
356      false edge as the value zero.  Note that those conditions are not
357      the same since only one of the outgoing edges from the COND_EXPR
358      will directly reach BB and thus be associated with an argument.  */
359   if ((e0 == true_edge && integer_onep (arg0))
360       || (e0 == false_edge && integer_zerop (arg0))
361       || (e1 == true_edge && integer_onep (arg1))
362       || (e1 == false_edge && integer_zerop (arg1)))
363     {
364       new = build (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
365     }
366   else
367     {
368       tree cond1 = invert_truthvalue (cond);
369
370       cond = cond1;
371       /* If what we get back is a conditional expression, there is no
372           way that it can be gimple.  */
373       if (TREE_CODE (cond) == COND_EXPR)
374         {
375           release_ssa_name (new_var1);
376           return false;
377         }
378
379       /* If what we get back is not gimple try to create it as gimple by
380          using a temporary variable.  */
381       if (is_gimple_cast (cond)
382           && !is_gimple_val (TREE_OPERAND (cond, 0)))
383         {
384           tree temp = TREE_OPERAND (cond, 0);
385           tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
386           new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
387           bsi_insert_after (&bsi, new, BSI_NEW_STMT);
388           cond = fold_convert (TREE_TYPE (result), new_var_1);
389         }
390
391       if (TREE_CODE (cond) == TRUTH_NOT_EXPR
392           &&  !is_gimple_val (TREE_OPERAND (cond, 0)))
393         {
394           release_ssa_name (new_var1);
395           return false;
396         }
397
398       new = build (MODIFY_EXPR, TREE_TYPE (new_var1), new_var1, cond);
399     }
400
401   bsi_insert_after (&bsi, new, BSI_NEW_STMT);
402
403   SSA_NAME_DEF_STMT (new_var1) = new;
404
405   replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, new_var1);
406
407   /* Note that we optimized this PHI.  */
408   return true;
409 }
410
411 /*  The function value_replacement does the main work of doing the value
412     replacement.  Return true if the replacement is done.  Otherwise return
413     false.
414     BB is the basic block where the replacement is going to be done on.  ARG0
415     is argument 0 from the PHI.  Likewise for ARG1.  */
416
417 static bool
418 value_replacement (basic_block cond_bb, basic_block middle_bb,
419                    basic_block phi_bb, edge e0, edge e1, tree phi,
420                    tree arg0, tree arg1)
421 {
422   tree result;
423   tree cond;
424   edge true_edge, false_edge;
425
426   /* If the type says honor signed zeros we cannot do this
427      optimization.  */
428   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
429     return false;
430
431   if (!empty_block_p (middle_bb))
432     return false;
433
434   cond = COND_EXPR_COND (last_stmt (cond_bb));
435   result = PHI_RESULT (phi);
436
437   /* This transformation is only valid for equality comparisons.  */
438   if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
439     return false;
440
441   /* We need to know which is the true edge and which is the false
442       edge so that we know if have abs or negative abs.  */
443   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
444
445   /* At this point we know we have a COND_EXPR with two successors.
446      One successor is BB, the other successor is an empty block which
447      falls through into BB.
448
449      The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
450
451      There is a single PHI node at the join point (BB) with two arguments.
452
453      We now need to verify that the two arguments in the PHI node match
454      the two arguments to the equality comparison.  */
455
456   if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
457        && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
458       || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
459           && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
460     {
461       edge e;
462       tree arg;
463
464       /* For NE_EXPR, we want to build an assignment result = arg where
465          arg is the PHI argument associated with the true edge.  For
466          EQ_EXPR we want the PHI argument associated with the false edge.  */
467       e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
468
469       /* Unfortunately, E may not reach BB (it may instead have gone to
470          OTHER_BLOCK).  If that is the case, then we want the single outgoing
471          edge from OTHER_BLOCK which reaches BB and represents the desired
472          path from COND_BLOCK.  */
473       if (e->dest == middle_bb)
474         e = EDGE_SUCC (e->dest, 0);
475
476       /* Now we know the incoming edge to BB that has the argument for the
477          RHS of our new assignment statement.  */
478       if (e0 == e)
479         arg = arg0;
480       else
481         arg = arg1;
482
483       replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, arg);
484
485       /* Note that we optimized this PHI.  */
486       return true;
487     }
488   return false;
489 }
490
491 /*  The function absolute_replacement does the main work of doing the absolute
492     replacement.  Return true if the replacement is done.  Otherwise return
493     false.
494     bb is the basic block where the replacement is going to be done on.  arg0
495     is argument 0 from the phi.  Likewise for arg1.   */
496
497 static bool
498 abs_replacement (basic_block cond_bb, basic_block middle_bb,
499                  basic_block phi_bb, edge e0 ATTRIBUTE_UNUSED, edge e1,
500                  tree phi, tree arg0, tree arg1)
501 {
502   tree result;
503   tree new, cond;
504   block_stmt_iterator bsi;
505   edge true_edge, false_edge;
506   tree assign = NULL;
507   edge e;
508   tree rhs = NULL, lhs = NULL;
509   bool negate;
510   enum tree_code cond_code;
511
512   /* If the type says honor signed zeros we cannot do this
513      optimization.  */
514   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
515     return false;
516
517   /* OTHER_BLOCK must have only one executable statement which must have the
518      form arg0 = -arg1 or arg1 = -arg0.  */
519   bsi = bsi_start (middle_bb);
520   while (!bsi_end_p (bsi))
521     {
522       tree stmt = bsi_stmt (bsi);
523
524       /* Empty statements and labels are uninteresting.  */
525       if (TREE_CODE (stmt) == LABEL_EXPR
526           || IS_EMPTY_STMT (stmt))
527         {
528           bsi_next (&bsi);
529           continue;
530         }
531
532       /* If we found the assignment, but it was not the only executable
533          statement in OTHER_BLOCK, then we can not optimize.  */
534       if (assign)
535         return false;
536
537       /* If we got here, then we have found the first executable statement
538          in OTHER_BLOCK.  If it is anything other than arg = -arg1 or
539          arg1 = -arg0, then we can not optimize.  */
540       if (TREE_CODE (stmt) == MODIFY_EXPR)
541         {
542           lhs = TREE_OPERAND (stmt, 0);
543           rhs = TREE_OPERAND (stmt, 1);
544
545           if (TREE_CODE (rhs) == NEGATE_EXPR)
546             {
547               rhs = TREE_OPERAND (rhs, 0);
548
549               /* The assignment has to be arg0 = -arg1 or arg1 = -arg0.  */
550               if ((lhs == arg0 && rhs == arg1)
551                   || (lhs == arg1 && rhs == arg0))
552                 {
553                   assign = stmt;
554                   bsi_next (&bsi);
555                 }
556               else
557                 return false;
558             }
559           else
560             return false;
561         }
562       else
563         return false;
564     }
565
566   /* If we did not find the proper negation assignment, then we can not
567      optimize.  */
568   if (assign == NULL)
569     return false;
570
571   cond = COND_EXPR_COND (last_stmt (cond_bb));
572   result = PHI_RESULT (phi);
573
574   /* Only relationals comparing arg[01] against zero are interesting.  */
575   cond_code = TREE_CODE (cond);
576   if (cond_code != GT_EXPR && cond_code != GE_EXPR
577       && cond_code != LT_EXPR && cond_code != LE_EXPR)
578     return false;
579
580   /* Make sure the conditional is arg[01] OP y.  */
581   if (TREE_OPERAND (cond, 0) != rhs)
582     return false;
583
584   if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
585                ? real_zerop (TREE_OPERAND (cond, 1))
586                : integer_zerop (TREE_OPERAND (cond, 1)))
587     ;
588   else
589     return false;
590
591   /* We need to know which is the true edge and which is the false
592      edge so that we know if have abs or negative abs.  */
593   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
594
595   /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
596      will need to negate the result.  Similarly for LT_EXPR/LE_EXPR if
597      the false edge goes to OTHER_BLOCK.  */
598   if (cond_code == GT_EXPR || cond_code == GE_EXPR)
599     e = true_edge;
600   else
601     e = false_edge;
602
603   if (e->dest == middle_bb)
604     negate = true;
605   else
606     negate = false;
607
608   result = duplicate_ssa_name (result, NULL);
609
610   if (negate)
611     lhs = make_rename_temp (TREE_TYPE (result), NULL);
612   else
613     lhs = result;
614
615   /* Build the modify expression with abs expression.  */
616   new = build (MODIFY_EXPR, TREE_TYPE (lhs),
617                lhs, build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
618
619   bsi = bsi_last (cond_bb);
620   bsi_insert_before (&bsi, new, BSI_NEW_STMT);
621
622   if (negate)
623     {
624       /* Get the right BSI.  We want to insert after the recently
625          added ABS_EXPR statement (which we know is the first statement
626          in the block.  */
627       new = build (MODIFY_EXPR, TREE_TYPE (result),
628                    result, build1 (NEGATE_EXPR, TREE_TYPE (lhs), lhs));
629
630       bsi_insert_after (&bsi, new, BSI_NEW_STMT);
631     }
632
633   SSA_NAME_DEF_STMT (result) = new;
634   replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, result);
635
636   /* Note that we optimized this PHI.  */
637   return true;
638 }
639
640
641 /* Always do these optimizations if we have SSA
642    trees to work on.  */
643 static bool
644 gate_phiopt (void)
645 {
646   return 1;
647 }
648
649 struct tree_opt_pass pass_phiopt =
650 {
651   "phiopt",                             /* name */
652   gate_phiopt,                          /* gate */
653   tree_ssa_phiopt,                      /* execute */
654   NULL,                                 /* sub */
655   NULL,                                 /* next */
656   0,                                    /* static_pass_number */
657   TV_TREE_PHIOPT,                       /* tv_id */
658   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
659   0,                                    /* properties_provided */
660   0,                                    /* properties_destroyed */
661   0,                                    /* todo_flags_start */
662   TODO_cleanup_cfg | TODO_dump_func | TODO_ggc_collect  /* todo_flags_finish */
663     | TODO_verify_ssa | TODO_rename_vars
664     | TODO_verify_flow | TODO_verify_stmts,
665   0                                     /* letter */
666 };