diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-07-11 18:14:48 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-07-11 18:14:48 +0000 |
commit | 9675412fd923871ec44eb30d70d3ef0f9d7811b6 (patch) | |
tree | 8ae61f65db968c0c276e91209918fc11f50b63e4 | |
parent | fa27426eb1377c2a9e23f58424b4da5497e78c8d (diff) | |
download | gcc-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/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/builtins.c | 5 | ||||
-rw-r--r-- | gcc/fold-const.c | 59 | ||||
-rw-r--r-- | gcc/tree-eh.c | 19 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 11 | ||||
-rw-r--r-- | gcc/tree.h | 1 |
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; } @@ -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); |