OSDN Git Service

PR target/21723
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-phiopt.c
index b935407..2f85948 100644 (file)
@@ -15,14 +15,13 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "errors.h"
 #include "ggc.h"
 #include "tree.h"
 #include "rtl.h"
@@ -37,16 +36,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "langhooks.h"
 
 static void tree_ssa_phiopt (void);
-static bool conditional_replacement (basic_block, basic_block, basic_block,
+static bool conditional_replacement (basic_block, basic_block,
                                     edge, edge, tree, tree, tree);
-static bool value_replacement (basic_block, basic_block, basic_block,
+static bool value_replacement (basic_block, basic_block,
                               edge, edge, tree, tree, tree);
-static bool minmax_replacement (basic_block, basic_block, basic_block,
+static bool minmax_replacement (basic_block, basic_block,
                                edge, edge, tree, tree, tree);
-static bool abs_replacement (basic_block, basic_block, basic_block,
+static bool abs_replacement (basic_block, basic_block,
                             edge, edge, tree, tree, tree);
-static void replace_phi_edge_with_variable (basic_block, basic_block, edge,
-                                           tree, tree);
+static void replace_phi_edge_with_variable (basic_block, edge, tree, tree);
 static basic_block *blocks_in_phiopt_order (void);
 
 /* This pass tries to replaces an if-then-else block with an
@@ -56,7 +54,7 @@ static basic_block *blocks_in_phiopt_order (void);
    Conditional Replacement
    -----------------------
 
-   This transformation, implmented in conditional_replacement,
+   This transformation, implemented in conditional_replacement,
    replaces
 
      bb0:
@@ -133,7 +131,7 @@ static basic_block *blocks_in_phiopt_order (void);
      bb2:
        x = PHI <x' (bb0), ...>;
 
-   A similar transformtion is done for MAX_EXPR.  */
+   A similar transformation is done for MAX_EXPR.  */
 
 static void
 tree_ssa_phiopt (void)
@@ -202,11 +200,12 @@ tree_ssa_phiopt (void)
       e1 = EDGE_SUCC (bb1, 0);
 
       /* Make sure that bb1 is just a fall through.  */
-      if (!single_succ_p (bb1) > 1
+      if (!single_succ_p (bb1)
          || (e1->flags & EDGE_FALLTHRU) == 0)
         continue;
 
-      /* Also make that bb1 only have one pred and it is bb.  */
+      /* Also make sure that bb1 only have one predecessor and that it
+        is bb.  */
       if (!single_pred_p (bb1)
           || single_pred (bb1) != bb)
        continue;
@@ -222,19 +221,19 @@ tree_ssa_phiopt (void)
       arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
       arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
 
-      /* We know something is wrong if we cannot find the edges in the PHI
+      /* Something is wrong if we cannot find the arguments in the PHI
         node.  */
       gcc_assert (arg0 != NULL && arg1 != NULL);
 
       /* Do the replacement of conditional if it can be done.  */
-      if (conditional_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
+      if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
        ;
-      else if (value_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
+      else if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
        ;
-      else if (abs_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1))
+      else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
        ;
       else
-       minmax_replacement (bb, bb1, bb2, e1, e2, phi, arg0, arg1);
+       minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1);
     }
 
   free (bb_order);
@@ -317,9 +316,10 @@ empty_block_p (basic_block bb)
    is known to have two edges, one of which must reach BB).  */
 
 static void
-replace_phi_edge_with_variable (basic_block cond_block, basic_block bb,
+replace_phi_edge_with_variable (basic_block cond_block,
                                edge e, tree phi, tree new)
 {
+  basic_block bb = bb_for_stmt (phi);
   basic_block block_to_remove;
   block_stmt_iterator bsi;
 
@@ -331,6 +331,8 @@ replace_phi_edge_with_variable (basic_block cond_block, basic_block bb,
     {
       EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
       EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
+      EDGE_SUCC (cond_block, 0)->probability = REG_BR_PROB_BASE;
+      EDGE_SUCC (cond_block, 0)->count += EDGE_SUCC (cond_block, 1)->count;
 
       block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
     }
@@ -339,6 +341,8 @@ replace_phi_edge_with_variable (basic_block cond_block, basic_block bb,
       EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
       EDGE_SUCC (cond_block, 1)->flags
        &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
+      EDGE_SUCC (cond_block, 1)->probability = REG_BR_PROB_BASE;
+      EDGE_SUCC (cond_block, 1)->count += EDGE_SUCC (cond_block, 0)->count;
 
       block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
     }
@@ -363,7 +367,7 @@ replace_phi_edge_with_variable (basic_block cond_block, basic_block bb,
 
 static bool
 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
-                        basic_block phi_bb, edge e0, edge e1, tree phi,
+                        edge e0, edge e1, tree phi,
                         tree arg0, tree arg1)
 {
   tree result;
@@ -495,7 +499,7 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
 
   SSA_NAME_DEF_STMT (new_var1) = new;
 
-  replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, new_var1);
+  replace_phi_edge_with_variable (cond_bb, e1, phi, new_var1);
 
   /* Note that we optimized this PHI.  */
   return true;
@@ -509,7 +513,7 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
 
 static bool
 value_replacement (basic_block cond_bb, basic_block middle_bb,
-                  basic_block phi_bb, edge e0, edge e1, tree phi,
+                  edge e0, edge e1, tree phi,
                   tree arg0, tree arg1)
 {
   tree cond;
@@ -571,7 +575,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
       else
        arg = arg1;
 
-      replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, arg);
+      replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
 
       /* Note that we optimized this PHI.  */
       return true;
@@ -587,7 +591,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
 
 static bool
 minmax_replacement (basic_block cond_bb, basic_block middle_bb,
-                   basic_block phi_bb, edge e0, edge e1, tree phi,
+                   edge e0, edge e1, tree phi,
                    tree arg0, tree arg1)
 {
   tree result, type;
@@ -720,8 +724,8 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
                return false;
 
              /* We need BOUND <= LARGER.  */
-             if (!integer_nonzerop (fold (build2 (LE_EXPR, boolean_type_node,
-                                                  bound, larger))))
+             if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
+                                                 bound, larger)))
                return false;
            }
          else if (operand_equal_for_phi_arg_p (arg_false, smaller))
@@ -745,8 +749,8 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
                return false;
 
              /* We need BOUND >= SMALLER.  */
-             if (!integer_nonzerop (fold (build2 (GE_EXPR, boolean_type_node,
-                                                  bound, smaller))))
+             if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
+                                                 bound, smaller)))
                return false;
            }
          else
@@ -779,8 +783,8 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
                return false;
 
              /* We need BOUND >= LARGER.  */
-             if (!integer_nonzerop (fold (build2 (GE_EXPR, boolean_type_node,
-                                                  bound, larger))))
+             if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
+                                                 bound, larger)))
                return false;
            }
          else if (operand_equal_for_phi_arg_p (arg_true, smaller))
@@ -804,8 +808,8 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
                return false;
 
              /* We need BOUND <= SMALLER.  */
-             if (!integer_nonzerop (fold (build2 (LE_EXPR, boolean_type_node,
-                                                  bound, smaller))))
+             if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
+                                                 bound, smaller)))
                return false;
            }
          else
@@ -826,7 +830,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
   bsi = bsi_last (cond_bb);
   bsi_insert_before (&bsi, new, BSI_NEW_STMT);
 
-  replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, result);
+  replace_phi_edge_with_variable (cond_bb, e1, phi, result);
   return true;
 }
 
@@ -838,7 +842,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
 
 static bool
 abs_replacement (basic_block cond_bb, basic_block middle_bb,
-                basic_block phi_bb, edge e0 ATTRIBUTE_UNUSED, edge e1,
+                edge e0 ATTRIBUTE_UNUSED, edge e1,
                 tree phi, tree arg0, tree arg1)
 {
   tree result;
@@ -947,7 +951,7 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
     }
 
   SSA_NAME_DEF_STMT (result) = new;
-  replace_phi_edge_with_variable (cond_bb, phi_bb, e1, phi, result);
+  replace_phi_edge_with_variable (cond_bb, e1, phi, result);
 
   /* Note that we optimized this PHI.  */
   return true;