OSDN Git Service

2010-06-22 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-ifcombine.c
index 1d2d85b..bc551b2 100644 (file)
@@ -1,5 +1,5 @@
 /* Combining of if-expressions on trees.
-   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
    Contributed by Richard Guenther <rguenther@suse.de>
 
 This file is part of GCC.
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "basic-block.h"
 #include "timevar.h"
-#include "diagnostic.h"
+#include "tree-pretty-print.h"
 #include "tree-flow.h"
 #include "tree-pass.h"
 #include "tree-dump.h"
@@ -340,6 +340,9 @@ ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
       t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
                                     true, GSI_SAME_STMT);
       t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
+      t = canonicalize_cond_expr_cond (t);
+      if (!t)
+       return false;
       gimple_cond_set_condition_from_tree (inner_cond, t);
       update_stmt (inner_cond);
 
@@ -363,21 +366,16 @@ ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
 
   /* See if we have two comparisons that we can merge into one.  */
   else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
-          && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
-          && operand_equal_p (gimple_cond_lhs (inner_cond),
-                              gimple_cond_lhs (outer_cond), 0)
-          && operand_equal_p (gimple_cond_rhs (inner_cond),
-                              gimple_cond_rhs (outer_cond), 0))
+          && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
     {
-      enum tree_code code1 = gimple_cond_code (inner_cond);
-      enum tree_code code2 = gimple_cond_code (outer_cond);
       tree t;
 
-      if (!(t = combine_comparisons (UNKNOWN_LOCATION,
-                                    TRUTH_ANDIF_EXPR, code1, code2,
-                                    boolean_type_node,
-                                    gimple_cond_lhs (outer_cond),
-                                    gimple_cond_rhs (outer_cond))))
+      if (!(t = maybe_fold_and_comparisons (gimple_cond_code (inner_cond),
+                                           gimple_cond_lhs (inner_cond),
+                                           gimple_cond_rhs (inner_cond),
+                                           gimple_cond_code (outer_cond),
+                                           gimple_cond_lhs (outer_cond),
+                                           gimple_cond_rhs (outer_cond))))
        return false;
       t = canonicalize_cond_expr_cond (t);
       if (!t)
@@ -488,6 +486,9 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
                                    true, GSI_SAME_STMT);
       t = fold_build2 (NE_EXPR, boolean_type_node, t,
                       build_int_cst (TREE_TYPE (t), 0));
+      t = canonicalize_cond_expr_cond (t);
+      if (!t)
+       return false;
       gimple_cond_set_condition_from_tree (inner_cond, t);
       update_stmt (inner_cond);
 
@@ -512,22 +513,17 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
   /* See if we have two comparisons that we can merge into one.
      This happens for C++ operator overloading where for example
      GE_EXPR is implemented as GT_EXPR || EQ_EXPR.  */
-  else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
-          && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
-          && operand_equal_p (gimple_cond_lhs (inner_cond),
-                              gimple_cond_lhs (outer_cond), 0)
-          && operand_equal_p (gimple_cond_rhs (inner_cond),
-                              gimple_cond_rhs (outer_cond), 0))
+    else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
+          && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
     {
-      enum tree_code code1 = gimple_cond_code (inner_cond);
-      enum tree_code code2 = gimple_cond_code (outer_cond);
       tree t;
 
-      if (!(t = combine_comparisons (UNKNOWN_LOCATION,
-                                    TRUTH_ORIF_EXPR, code1, code2,
-                                    boolean_type_node,
-                                    gimple_cond_lhs (outer_cond),
-                                    gimple_cond_rhs (outer_cond))))
+      if (!(t = maybe_fold_or_comparisons (gimple_cond_code (inner_cond),
+                                          gimple_cond_lhs (inner_cond),
+                                          gimple_cond_rhs (inner_cond),
+                                          gimple_cond_code (outer_cond),
+                                          gimple_cond_lhs (outer_cond),
+                                          gimple_cond_rhs (outer_cond))))
        return false;
       t = canonicalize_cond_expr_cond (t);
       if (!t)
@@ -651,7 +647,7 @@ gate_ifcombine (void)
   return 1;
 }
 
-struct gimple_opt_pass pass_tree_ifcombine = 
+struct gimple_opt_pass pass_tree_ifcombine =
 {
  {
   GIMPLE_PASS,