OSDN Git Service

/c-family
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-reassoc.c
index 790635c..987ec65 100644 (file)
@@ -1,5 +1,6 @@
 /* Reassociation for trees.
-   Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
    Contributed by Daniel Berlin <dan@dberlin.org>
 
 This file is part of GCC.
@@ -1279,6 +1280,20 @@ eliminate_redundant_comparison (enum tree_code opcode,
       if (!useless_type_conversion_p (TREE_TYPE (curr->op), TREE_TYPE (t)))
        t = fold_convert (TREE_TYPE (curr->op), t);
 
+      if (TREE_CODE (t) != INTEGER_CST
+         && !operand_equal_p (t, curr->op, 0))
+       {
+         enum tree_code subcode;
+         tree newop1, newop2;
+         if (!COMPARISON_CLASS_P (t))
+           continue;
+         extract_ops_from_tree (t, &subcode, &newop1, &newop2);
+         STRIP_USELESS_TYPE_CONVERSION (newop1);
+         STRIP_USELESS_TYPE_CONVERSION (newop2);
+         if (!is_gimple_val (newop1) || !is_gimple_val (newop2))
+           continue;
+       }
+
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "Equivalence: ");
@@ -1786,13 +1801,15 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, gimple stmt,
   if (TREE_CODE (binlhs) == SSA_NAME)
     {
       binlhsdef = SSA_NAME_DEF_STMT (binlhs);
-      binlhsisreassoc = is_reassociable_op (binlhsdef, rhscode, loop);
+      binlhsisreassoc = (is_reassociable_op (binlhsdef, rhscode, loop)
+                        && !stmt_could_throw_p (binlhsdef));
     }
 
   if (TREE_CODE (binrhs) == SSA_NAME)
     {
       binrhsdef = SSA_NAME_DEF_STMT (binrhs);
-      binrhsisreassoc = is_reassociable_op (binrhsdef, rhscode, loop);
+      binrhsisreassoc = (is_reassociable_op (binrhsdef, rhscode, loop)
+                        && !stmt_could_throw_p (binrhsdef));
     }
 
   /* If the LHS is not reassociable, but the RHS is, we need to swap
@@ -2027,7 +2044,8 @@ reassociate_bb (basic_block bb)
     {
       gimple stmt = gsi_stmt (gsi);
 
-      if (is_gimple_assign (stmt))
+      if (is_gimple_assign (stmt)
+         && !stmt_could_throw_p (stmt))
        {
          tree lhs, rhs1, rhs2;
          enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
@@ -2279,7 +2297,10 @@ struct gimple_opt_pass pass_reassoc =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+  TODO_verify_ssa
+    | TODO_verify_flow
+    | TODO_dump_func
+    | TODO_ggc_collect                 /* todo_flags_finish */
  }
 };