aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2004-07-11 18:14:48 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2004-07-11 18:14:48 +0000
commit9675412fd923871ec44eb30d70d3ef0f9d7811b6 (patch)
tree8ae61f65db968c0c276e91209918fc11f50b63e4
parentfa27426eb1377c2a9e23f58424b4da5497e78c8d (diff)
downloadgcc-9675412fd923871ec44eb30d70d3ef0f9d7811b6.zip
gcc-9675412fd923871ec44eb30d70d3ef0f9d7811b6.tar.gz
gcc-9675412fd923871ec44eb30d70d3ef0f9d7811b6.tar.bz2
builtins.c (fold_builtin_fputs): Don't bother converting the return type to integer_type_node...
* 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
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/builtins.c5
-rw-r--r--gcc/fold-const.c59
-rw-r--r--gcc/tree-eh.c19
-rw-r--r--gcc/tree-ssa-ccp.c11
-rw-r--r--gcc/tree.h1
6 files changed, 100 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 155e343..3ff14d4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 02fdc92..5b2a63f 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index b35dfbf..f1927f2 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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 ();
}
@@ -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"
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 8ff1bfa..b0638c0 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -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:
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 5b6fca6..7f28a9f 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -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;
}
diff --git a/gcc/tree.h b/gcc/tree.h
index baa2078..75f4f28 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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);