OSDN Git Service

PR middle-end/46844
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-reassoc.c
index 6cd3ceb..197591e 100644 (file)
@@ -467,8 +467,7 @@ eliminate_duplicate_pair (enum tree_code opcode,
            {
              VEC_free (operand_entry_t, heap, *ops);
              *ops = NULL;
-             add_to_ops_vec (ops, fold_convert (TREE_TYPE (last->op),
-                                                integer_zero_node));
+             add_to_ops_vec (ops, build_zero_cst (TREE_TYPE (last->op)));
              *all_done = true;
            }
          else
@@ -535,8 +534,7 @@ eliminate_plus_minus_pair (enum tree_code opcode,
            }
 
          VEC_ordered_remove (operand_entry_t, *ops, i);
-         add_to_ops_vec (ops, fold_convert(TREE_TYPE (oe->op),
-                                           integer_zero_node));
+         add_to_ops_vec (ops, build_zero_cst (TREE_TYPE (oe->op)));
          VEC_ordered_remove (operand_entry_t, *ops, currindex);
          reassociate_stats.ops_eliminated ++;
 
@@ -623,7 +621,7 @@ eliminate_not_pairs (enum tree_code opcode,
            }
 
          if (opcode == BIT_AND_EXPR)
-           oe->op = fold_convert (TREE_TYPE (oe->op), integer_zero_node);
+           oe->op = build_zero_cst (TREE_TYPE (oe->op));
          else if (opcode == BIT_IOR_EXPR)
            oe->op = build_low_bits_mask (TREE_TYPE (oe->op),
                                          TYPE_PRECISION (TREE_TYPE (oe->op)));
@@ -1016,7 +1014,7 @@ undistribute_ops_list (enum tree_code opcode,
   candidates = sbitmap_alloc (length);
   sbitmap_zero (candidates);
   nr_candidates = 0;
-  for (i = 0; VEC_iterate (operand_entry_t, *ops, i, oe1); ++i)
+  FOR_EACH_VEC_ELT (operand_entry_t, *ops, i, oe1)
     {
       enum tree_code dcode;
       gimple oe1def;
@@ -1067,7 +1065,7 @@ undistribute_ops_list (enum tree_code opcode,
       linearize_expr_tree (&subops[i], oedef,
                           associative_tree_code (oecode), false);
 
-      for (j = 0; VEC_iterate (operand_entry_t, subops[i], j, oe1); ++j)
+      FOR_EACH_VEC_ELT (operand_entry_t, subops[i], j, oe1)
        {
          oecount c;
          void **slot;
@@ -1093,14 +1091,13 @@ undistribute_ops_list (enum tree_code opcode,
   htab_delete (ctable);
 
   /* Sort the counting table.  */
-  qsort (VEC_address (oecount, cvec), VEC_length (oecount, cvec),
-        sizeof (oecount), oecount_cmp);
+  VEC_qsort (oecount, cvec, oecount_cmp);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       oecount *c;
       fprintf (dump_file, "Candidates:\n");
-      for (j = 0; VEC_iterate (oecount, cvec, j, c); ++j)
+      FOR_EACH_VEC_ELT (oecount, cvec, j, c)
        {
          fprintf (dump_file, "  %u %s: ", c->cnt,
                   c->oecode == MULT_EXPR
@@ -1139,7 +1136,7 @@ undistribute_ops_list (enum tree_code opcode,
          if (oecode != c->oecode)
            continue;
 
-         for (j = 0; VEC_iterate (operand_entry_t, subops[i], j, oe1); ++j)
+         FOR_EACH_VEC_ELT (operand_entry_t, subops[i], j, oe1)
            {
              if (oe1->op == c->op)
                {
@@ -1178,7 +1175,7 @@ undistribute_ops_list (enum tree_code opcode,
                }
              zero_one_operation (&oe2->op, c->oecode, c->op);
              sum = build_and_add_sum (tmpvar, oe1->op, oe2->op, opcode);
-             oe2->op = fold_convert (TREE_TYPE (oe2->op), integer_zero_node);
+             oe2->op = build_zero_cst (TREE_TYPE (oe2->op));
              oe2->rank = 0;
              oe1->op = gimple_get_lhs (sum);
            }
@@ -1314,9 +1311,14 @@ eliminate_redundant_comparison (enum tree_code opcode,
          enum tree_code subcode;
          tree newop1;
          tree newop2;
+         gcc_assert (COMPARISON_CLASS_P (t));
          tmpvar = create_tmp_var (TREE_TYPE (t), NULL);
          add_referenced_var (tmpvar);
          extract_ops_from_tree (t, &subcode, &newop1, &newop2);
+         STRIP_USELESS_TYPE_CONVERSION (newop1);
+         STRIP_USELESS_TYPE_CONVERSION (newop2);
+         gcc_checking_assert (is_gimple_val (newop1)
+                              && is_gimple_val (newop2));
          sum = build_and_add_sum (tmpvar, newop1, newop2, subcode);
          curr->op = gimple_get_lhs (sum);
        }
@@ -1784,13 +1786,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
@@ -1864,7 +1868,7 @@ repropagate_negates (void)
   unsigned int i = 0;
   tree negate;
 
-  for (i = 0; VEC_iterate (tree, plus_negates, i, negate); i++)
+  FOR_EACH_VEC_ELT (tree, plus_negates, i, negate)
     {
       gimple user = get_single_immediate_use (negate);
 
@@ -1949,7 +1953,7 @@ static bool
 can_reassociate_p (tree op)
 {
   tree type = TREE_TYPE (op);
-  if (INTEGRAL_TYPE_P (type)
+  if ((INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
       || NON_SAT_FIXED_POINT_TYPE_P (type)
       || (flag_associative_math && FLOAT_TYPE_P (type)))
     return true;
@@ -2025,7 +2029,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);
@@ -2065,9 +2070,16 @@ reassociate_bb (basic_block bb)
          rhs1 = gimple_assign_rhs1 (stmt);
          rhs2 = gimple_assign_rhs2 (stmt);
 
-         if (!can_reassociate_p (lhs)
-             || !can_reassociate_p (rhs1)
-             || !can_reassociate_p (rhs2))
+         /* For non-bit or min/max operations we can't associate
+            all types.  Verify that here.  */
+         if (rhs_code != BIT_IOR_EXPR
+             && rhs_code != BIT_AND_EXPR
+             && rhs_code != BIT_XOR_EXPR
+             && rhs_code != MIN_EXPR
+             && rhs_code != MAX_EXPR
+             && (!can_reassociate_p (lhs)
+                 || !can_reassociate_p (rhs1)
+                 || !can_reassociate_p (rhs2)))
            continue;
 
          if (associative_tree_code (rhs_code))
@@ -2081,18 +2093,12 @@ reassociate_bb (basic_block bb)
 
              gimple_set_visited (stmt, true);
              linearize_expr_tree (&ops, stmt, true, true);
-             qsort (VEC_address (operand_entry_t, ops),
-                    VEC_length (operand_entry_t, ops),
-                    sizeof (operand_entry_t),
-                    sort_by_operand_rank);
+             VEC_qsort (operand_entry_t, ops, sort_by_operand_rank);
              optimize_ops_list (rhs_code, &ops);
              if (undistribute_ops_list (rhs_code, &ops,
                                         loop_containing_stmt (stmt)))
                {
-                 qsort (VEC_address (operand_entry_t, ops),
-                        VEC_length (operand_entry_t, ops),
-                        sizeof (operand_entry_t),
-                        sort_by_operand_rank);
+                 VEC_qsort (operand_entry_t, ops, sort_by_operand_rank);
                  optimize_ops_list (rhs_code, &ops);
                }
 
@@ -2141,7 +2147,7 @@ dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops)
   operand_entry_t oe;
   unsigned int i;
 
-  for (i = 0; VEC_iterate (operand_entry_t, ops, i, oe); i++)
+  FOR_EACH_VEC_ELT (operand_entry_t, ops, i, oe)
     {
       fprintf (file, "Op %d -> rank: %d, tree: ", i, oe->rank);
       print_generic_expr (file, oe->op, 0);