builtins.c (fold_builtin_fputs): Don't bother converting the return type to integer_t...
authorRoger Sayle <roger@eyesopen.com>
Sun, 11 Jul 2004 18:14:48 +0000 (18:14 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sun, 11 Jul 2004 18:14:48 +0000 (18:14 +0000)
* builtins.c (fold_builtin_fputs): Don't bother converting the
return type to integer_type_node, as we've already checked that
the result will be ignored.

* tree-eh.c (tree_could_trap_p): Add support for -ftrapv such
that signed addition, subtraction, multiplication, division,
remainder, negation and absolute value may potentially trap.

* fold-const.c (fold_ignored_result): New function to strip
non-side-effecting tree nodes from an expression whose result
is ignored.
(fold_convert): Call fold_ignored_result when casting a value
to VOID_TYPE.
(omit_one_operand):  Call fold_ignored_result on the "omitted"
operand when building a COMPOUND_EXPR.
(pedantic_omit_one_operand): Likewise.
* tree.h (fold_ignored_result): Prototype here.
* tree-ssa-ccp.c (ccp_fold_builtin): Call fold_ignored_result
when we're going to ignore the result.

From-SVN: r84525

gcc/ChangeLog
gcc/builtins.c
gcc/fold-const.c
gcc/tree-eh.c
gcc/tree-ssa-ccp.c
gcc/tree.h

index 155e3436738674eb770b37a2bc185f8a15863485..3ff14d40a3a2f6a98d5923c9eef7a51aea27c379 100644 (file)
@@ -1,3 +1,25 @@
+2004-07-11  Roger Sayle  <roger@eyesopen.com>
+
+       * builtins.c (fold_builtin_fputs): Don't bother converting the
+       return type to integer_type_node, as we've already checked that
+       the result will be ignored.
+
+       * tree-eh.c (tree_could_trap_p): Add support for -ftrapv such
+       that signed addition, subtraction, multiplication, division,
+       remainder, negation and absolute value may potentially trap.
+
+       * fold-const.c (fold_ignored_result): New function to strip
+       non-side-effecting tree nodes from an expression whose result
+       is ignored.
+       (fold_convert): Call fold_ignored_result when casting a value
+       to VOID_TYPE.
+       (omit_one_operand):  Call fold_ignored_result on the "omitted"
+       operand when building a COMPOUND_EXPR.
+       (pedantic_omit_one_operand): Likewise.
+       * tree.h (fold_ignored_result): Prototype here.
+       * tree-ssa-ccp.c (ccp_fold_builtin): Call fold_ignored_result
+       when we're going to ignore the result.
+
 2004-07-11  Richard Henderson  <rth@redhat.com>
 
        PR tree-opt/16383
index 02fdc929b41b97a3bf1171cef5bc12b61a2c9126..5b2a63ff9428b571bff2e72c3932a32be423023a 100644 (file)
@@ -9474,8 +9474,9 @@ fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
       abort ();
     }
 
-  return fold_convert (integer_type_node,
-                      build_function_call_expr (fn, arglist));
+  /* These optimizations are only performed when the result is ignored,
+     hence there's no need to cast the result to integer_type_node.  */
+  return build_function_call_expr (fn, arglist);
 }
 
 static void
index b35dfbf390319553bd69bf7eedaa0cf7953f7e98..f1927f27995e48e48db5cbb0df0324df075aca40 100644 (file)
@@ -1999,7 +1999,7 @@ fold_convert (tree type, tree arg)
        return fold (build1 (NOP_EXPR, type, arg));
     }
   else if (VOID_TYPE_P (type))
-    return fold (build1 (CONVERT_EXPR, type, arg));
+    return fold (build1 (CONVERT_EXPR, type, fold_ignored_result (arg)));
   abort ();
 }
 \f
@@ -2828,7 +2828,7 @@ omit_one_operand (tree type, tree result, tree omitted)
   tree t = fold_convert (type, result);
 
   if (TREE_SIDE_EFFECTS (omitted))
-    return build2 (COMPOUND_EXPR, type, omitted, t);
+    return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
 
   return non_lvalue (t);
 }
@@ -2841,7 +2841,7 @@ pedantic_omit_one_operand (tree type, tree result, tree omitted)
   tree t = fold_convert (type, result);
 
   if (TREE_SIDE_EFFECTS (omitted))
-    return build2 (COMPOUND_EXPR, type, omitted, t);
+    return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);
 
   return pedantic_non_lvalue (t);
 }
@@ -10583,4 +10583,57 @@ build_fold_indirect_ref (tree t)
   return build1 (INDIRECT_REF, type, t);
 }
 
+/* Strip non-trapping, non-side-effecting tree nodes from an expression
+   whose result is ignored.  The type of the returned tree need not be
+   the same as the original expression.  */
+
+tree
+fold_ignored_result (tree t)
+{
+  if (!TREE_SIDE_EFFECTS (t))
+    return integer_zero_node;
+
+  for (;;)
+    switch (TREE_CODE_CLASS (TREE_CODE (t)))
+      {
+      case '1':
+       t = TREE_OPERAND (t, 0);
+       break;
+
+      case '2':
+      case '<':
+       if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
+         t = TREE_OPERAND (t, 0);
+       else if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0)))
+         t = TREE_OPERAND (t, 1);
+       else
+         return t;
+       break;
+
+      case 'e':
+       switch (TREE_CODE (t))
+         {
+         case COMPOUND_EXPR:
+           if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
+             return t;
+           t = TREE_OPERAND (t, 0);
+           break;
+
+         case COND_EXPR:
+           if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1))
+               || TREE_SIDE_EFFECTS (TREE_OPERAND (t, 2)))
+             return t;
+           t = TREE_OPERAND (t, 0);
+           break;
+
+         default:
+           return t;
+         }
+       break;
+
+      default:
+       return t;
+      }
+}
+
 #include "gt-fold-const.h"
index 8ff1bfa55b70a97bd9539d4a3855c12e9705e693..b0638c001084b75d5e683472f15a02103bb044f5 100644 (file)
@@ -1705,6 +1705,7 @@ tree_could_trap_p (tree expr)
   bool honor_nans = false;
   bool honor_snans = false;
   bool fp_operation = false;
+  bool honor_trapv = false;
   tree t, base, idx;
 
   if (TREE_CODE_CLASS (code) == '<'
@@ -1718,6 +1719,8 @@ tree_could_trap_p (tree expr)
          honor_nans = flag_trapping_math && !flag_finite_math_only;
          honor_snans = flag_signaling_nans != 0;
        }
+      else if (INTEGRAL_TYPE_P (t) && TYPE_TRAP_SIGNED (t))
+       honor_trapv = true;
     }
 
   switch (code)
@@ -1765,7 +1768,7 @@ tree_could_trap_p (tree expr)
     case ROUND_MOD_EXPR:
     case TRUNC_MOD_EXPR:
     case RDIV_EXPR:
-      if (honor_snans)
+      if (honor_snans || honor_trapv)
        return true;
       if (fp_operation && flag_trapping_math)
        return true;
@@ -1804,7 +1807,19 @@ tree_could_trap_p (tree expr)
     case NEGATE_EXPR:
     case ABS_EXPR:
     case CONJ_EXPR:
-      /* These operations don't trap even with floating point.  */
+      /* These operations don't trap with floating point.  */
+      if (honor_trapv)
+       return true;
+      return false;
+
+    case PLUS_EXPR:
+    case MINUS_EXPR:
+    case MULT_EXPR:
+      /* Any floating arithmetic may trap.  */
+      if (fp_operation && flag_trapping_math)
+       return true;
+      if (honor_trapv)
+       return true;
       return false;
 
     default:
index 5b6fca62653b523c4016cdfa1680e1016c8e802b..7f28a9f9e93b5ff1b28e871aca271fe85deca845 100644 (file)
@@ -2386,16 +2386,7 @@ ccp_fold_builtin (tree stmt, tree fn)
     }
 
   if (result && ignore)
-    {
-      /* STRIP_NOPS isn't strong enough -- it'll stop when we change modes,
-        but given that we're ignoring the result, we don't care what type
-        is being returned by the transformed function.  */
-      while (TREE_CODE (result) == NOP_EXPR
-            || TREE_CODE (result) == CONVERT_EXPR
-            || TREE_CODE (result) == NON_LVALUE_EXPR)
-       result = TREE_OPERAND (result, 0);
-    }
-
+    result = fold_ignored_result (result);
   return result;
 }
 
index baa20781eefc8dbf3fb21e0fdb835e789128825d..75f4f285add913b970c99d24e25138b8bf6fbe90 100644 (file)
@@ -3372,6 +3372,7 @@ extern tree fold (tree);
 extern tree fold_initializer (tree);
 extern tree fold_convert (tree, tree);
 extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
+extern tree fold_ignored_result (tree);
 extern tree fold_abs_const (tree, tree);
 
 extern int force_fit_type (tree, int);