diff options
author | Richard Guenther <rguenther@suse.de> | 2011-03-24 11:23:29 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-03-24 11:23:29 +0000 |
commit | cfef45c8097d122e7dfda42c5e2767bf21a7f649 (patch) | |
tree | df3f9f4a9233142004cc074157b5b3c2abf3bcb5 /gcc/tree-ssa-sccvn.c | |
parent | f3e8ab1973c02daace2d7be9dbf03be03a7b3669 (diff) | |
download | gcc-cfef45c8097d122e7dfda42c5e2767bf21a7f649.zip gcc-cfef45c8097d122e7dfda42c5e2767bf21a7f649.tar.gz gcc-cfef45c8097d122e7dfda42c5e2767bf21a7f649.tar.bz2 |
re PR tree-optimization/46562 (CCP currently needs iteration for &a[i])
2011-03-24 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46562
* tree.c (build_invariant_address): New function.
* tree.h (build_invariant_address): Declare.
* tree-dfa.c (get_addr_base_and_unit_offset): Wrap around
a renamed function moved ...
* tree-flow-inline.h (get_addr_base_and_unit_offset_1): ... here.
Take valueization callback parameter.
* tree-flow.h (gimple_fold_stmt_to_constant): Declare.
* gimple-fold.h: New file.
* tree-ssa-ccp.c (ccp_fold): Use gimple_fold_stmt_to_constant_1.
(ccp_fold, fold_const_aggregate_ref,
fold_ctor_reference, fold_nonarray_ctor_reference,
fold_array_ctor_reference, fold_string_cst_ctor_reference,
get_base_constructor): Move ...
* gimple-fold.c: ... here.
(gimple_fold_stmt_to_constant_1): New function
split out from ccp_fold. Take a valueization callback parameter.
Valueize all operands.
(gimple_fold_stmt_to_constant): New wrapper function.
(fold_const_aggregate_ref_1): New function split out from
fold_const_aggregate_ref. Take a valueization callback parameter.
(fold_const_aggregate_ref): Wrap fold_const_aggregate_ref_1.
* tree-ssa-sccvn.c (simplify_binary_expression): Simplify
invariant POINTER_PLUS_EXPRs to invariant form.
(vn_valueize): New function.
(try_to_simplify): Simplify by using gimple_fold_stmt_to_constant.
* tree-vrp.c (vrp_valueize): New function.
(vrp_visit_assignment_or_call): Use gimple_fold_stmt_to_constant
to fold statements to constants.
* tree-ssa-pre.c (eliminate): Properly guard propagation of
function declarations.
* Makefile.in (tree-ssa-sccvn.o, tree-vrp.o, gimple-fold.o,
tree-ssa-ccp.o): Add gimple-fold.h dependencies.
* c-c++-common/pr46562-2.c: New testcase.
* c-c++-common/pr46562.c: Likewise.
From-SVN: r171386
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index a346243..29b80ea 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "tree-ssa-propagate.h" #include "tree-ssa-sccvn.h" +#include "gimple-fold.h" /* This algorithm is based on the SCC algorithm presented by Keith Cooper and L. Taylor Simpson in "SCC-Based Value numbering" @@ -2770,6 +2771,16 @@ simplify_binary_expression (gimple stmt) op1 = SSA_VAL (op1); } + /* Pointer plus constant can be represented as invariant address. + Do so to allow further propatation, see also tree forwprop. */ + if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR + && host_integerp (op1, 1) + && TREE_CODE (op0) == ADDR_EXPR + && is_gimple_min_invariant (op0)) + return build_invariant_address (TREE_TYPE (op0), + TREE_OPERAND (op0, 0), + TREE_INT_CST_LOW (op1)); + /* Avoid folding if nothing changed. */ if (op0 == gimple_assign_rhs1 (stmt) && op1 == gimple_assign_rhs2 (stmt)) @@ -2849,6 +2860,19 @@ simplify_unary_expression (gimple stmt) return NULL_TREE; } +/* Valueize NAME if it is an SSA name, otherwise just return it. */ + +static inline tree +vn_valueize (tree name) +{ + if (TREE_CODE (name) == SSA_NAME) + { + tree tem = SSA_VAL (name); + return tem == VN_TOP ? name : tem; + } + return name; +} + /* Try to simplify RHS using equivalences and constant folding. */ static tree @@ -2862,21 +2886,15 @@ try_to_simplify (gimple stmt) && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME) return NULL_TREE; + /* First try constant folding based on our current lattice. */ + tem = gimple_fold_stmt_to_constant (stmt, vn_valueize); + if (tem) + return tem; + + /* If that didn't work try combining multiple statements. */ switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))) { - case tcc_declaration: - tem = get_symbol_constant_value (gimple_assign_rhs1 (stmt)); - if (tem) - return tem; - break; - case tcc_reference: - /* Do not do full-blown reference lookup here, but simplify - reads from constant aggregates. */ - tem = fold_const_aggregate_ref (gimple_assign_rhs1 (stmt)); - if (tem) - return tem; - /* Fallthrough for some codes that can operate on registers. */ if (!(TREE_CODE (gimple_assign_rhs1 (stmt)) == REALPART_EXPR || TREE_CODE (gimple_assign_rhs1 (stmt)) == IMAGPART_EXPR @@ -2886,11 +2904,11 @@ try_to_simplify (gimple stmt) into binary ops, but it's debatable whether it is worth it. */ case tcc_unary: return simplify_unary_expression (stmt); - break; + case tcc_comparison: case tcc_binary: return simplify_binary_expression (stmt); - break; + default: break; } |