diff options
author | Richard Guenther <rguenther@suse.de> | 2008-08-08 15:01:05 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-08-08 15:01:05 +0000 |
commit | 174ef36d7223171145b3d3eed56b6ebb9a5d63d9 (patch) | |
tree | a4edba721d11775cb5881bd39e35b3624e96afb6 /gcc | |
parent | 70d904ca8edc145e16c7d5720059eb437e439ee2 (diff) | |
download | gcc-174ef36d7223171145b3d3eed56b6ebb9a5d63d9.zip gcc-174ef36d7223171145b3d3eed56b6ebb9a5d63d9.tar.gz gcc-174ef36d7223171145b3d3eed56b6ebb9a5d63d9.tar.bz2 |
tree-ssa-ccp.c (likely_value): Calls are not all varying.
2008-08-08 Richard Guenther <rguenther@suse.de>
* tree-ssa-ccp.c (likely_value): Calls are not all varying.
(surely_varying_stmt_p): Calls are varying only if they are
non-builtin and not indirect or have no result.
(ccp_fold): Re-instantiate code before the tuples merge.
* gcc.dg/tree-ssa/ssa-ccp-20.c: New testcase.
From-SVN: r138882
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-20.c | 15 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 66 |
4 files changed, 75 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3ba567..5c6811c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2008-08-08 Richard Guenther <rguenther@suse.de> + * tree-ssa-ccp.c (likely_value): Calls are not all varying. + (surely_varying_stmt_p): Calls are varying only if they are + non-builtin and not indirect or have no result. + (ccp_fold): Re-instantiate code before the tuples merge. + +2008-08-08 Richard Guenther <rguenther@suse.de> + PR tree-optimization/37056 * gimple.h (gimple_assign_rhs_class): New helper function. * tree-ssa-loop-niter.c (get_val_for): Fix tuplification, handle diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d930e38..ba897b0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2008-08-08 Richard Guenther <rguenther@suse.de> + * gcc.dg/tree-ssa/ssa-ccp-20.c: New testcase. + +2008-08-08 Richard Guenther <rguenther@suse.de> + PR tree-optimization/37056 * gcc.c-torture/compile/pr37056.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-20.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-20.c new file mode 100644 index 0000000..63febd0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-20.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-ccp1" } */ + +/* Make sure CCP propagates through indirect calls. */ + +int foo (void) +{ + int i = -5; + int (*fn)(int) = __builtin_abs; + int j = fn(i); + return j + 5; +} + +/* { dg-final { scan-tree-dump "return 10;" "ccp1" } } */ +/* { dg-final { cleanup-tree-dump "ccp1" } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index b867bba..af102cd 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -528,17 +528,10 @@ likely_value (gimple stmt) && !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)) return VARYING; - /* A GIMPLE_CALL is assumed to be varying. NOTE: This may be overly - conservative, in the presence of const and pure calls. */ - if (code == GIMPLE_CALL) - return VARYING; - /* Note that only a GIMPLE_SINGLE_RHS assignment can satisfy is_gimple_min_invariant, so we do not consider calls or other forms of assignment. */ - if (code == GIMPLE_ASSIGN - && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) - == GIMPLE_SINGLE_RHS) + if (gimple_assign_single_p (stmt) && is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) return CONSTANT; @@ -630,15 +623,23 @@ surely_varying_stmt_p (gimple stmt) return true; } - /* If it contains a call, it is varying. */ + /* If it is a call and does not return a value or is not a + builtin and not an indirect call, it is varying. */ if (is_gimple_call (stmt)) - return true; + { + tree fndecl; + if (!gimple_call_lhs (stmt) + || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE + && DECL_BUILT_IN (fndecl))) + return true; + } /* Anything other than assignments and conditional jumps are not interesting for CCP. */ if (gimple_code (stmt) != GIMPLE_ASSIGN - && (gimple_code (stmt) != GIMPLE_COND) - && (gimple_code (stmt) != GIMPLE_SWITCH)) + && gimple_code (stmt) != GIMPLE_COND + && gimple_code (stmt) != GIMPLE_SWITCH + && gimple_code (stmt) != GIMPLE_CALL) return true; return false; @@ -1034,11 +1035,42 @@ ccp_fold (gimple stmt) break; case GIMPLE_CALL: - /* It may be possible to fold away calls to builtin functions if - their arguments are constants. At present, such folding will not - be attempted, as likely_value classifies all calls as VARYING. */ - gcc_unreachable (); - break; + { + tree fn = gimple_call_fn (stmt); + prop_value_t *val; + + if (TREE_CODE (fn) == SSA_NAME) + { + val = get_value (fn); + if (val->lattice_val == CONSTANT) + fn = val->value; + } + if (TREE_CODE (fn) == ADDR_EXPR + && DECL_BUILT_IN (TREE_OPERAND (fn, 0))) + { + tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt)); + tree call, retval; + unsigned i; + for (i = 0; i < gimple_call_num_args (stmt); ++i) + { + args[i] = gimple_call_arg (stmt, i); + if (TREE_CODE (args[i]) == SSA_NAME) + { + val = get_value (args[i]); + if (val->lattice_val == CONSTANT) + args[i] = val->value; + } + } + call = build_call_array (gimple_call_return_type (stmt), + fn, gimple_call_num_args (stmt), args); + retval = fold_call_expr (call, false); + if (retval) + /* fold_call_expr wraps the result inside a NOP_EXPR. */ + STRIP_NOPS (retval); + return retval; + } + return NULL_TREE; + } case GIMPLE_COND: { |