diff options
author | Richard Guenther <rguenther@suse.de> | 2008-07-29 17:09:26 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-07-29 17:09:26 +0000 |
commit | ce94d3547f81cc3dd105f4a3377e72cdbd2bbd2c (patch) | |
tree | d2185d79e36deb34f5ad3885547df3a1a15064b0 /gcc/tree-ssa-sccvn.c | |
parent | 0f3a057aa9e5b4f6fbdbee87e8224ca9ea5a6d83 (diff) | |
download | gcc-ce94d3547f81cc3dd105f4a3377e72cdbd2bbd2c.tar.gz |
re PR tree-optimization/36945 (PRE/SCCVN do not handle aggregate function arguments correctly)
2008-07-29 Richard Guenther <rguenther@suse.de>
PR tree-optimization/36945
* tree-ssa-sccvn.h (copy_reference_ops_from_ref): Declare.
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Export.
Record invariant addresses un-decomposed.
(copy_reference_ops_from_call): Record reference call
arguments properly. Simplify.
* tree-ssa-pre.c (create_component_ref_by_pieces_1): New
helper split out from ...
(create_component_ref_by_pieces): ... here. Simplify.
Prepare for recursive invocation for call arguments.
(create_expression_by_pieces): Adjust call to
create_component_ref_by_pieces.
(compute_avail): Process operand 2 of reference ops.
* gcc.dg/tree-ssa/ssa-pre-18.c: New testcase.
From-SVN: r138257
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 42d394f5540..f6492bdafd8 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -557,7 +557,7 @@ shared_vuses_from_stmt (gimple stmt) /* Copy the operations present in load/store REF into RESULT, a vector of vn_reference_op_s's. */ -static void +void copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result) { if (TREE_CODE (ref) == TARGET_MEM_REF) @@ -646,6 +646,13 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result) case SSA_NAME: temp.op0 = ref; break; + case ADDR_EXPR: + if (is_gimple_min_invariant (ref)) + { + temp.op0 = ref; + break; + } + /* Fallthrough. */ /* These are only interesting for their operands, their existence, and their type. They will never be the last ref in the chain of references (IE they require an @@ -654,15 +661,15 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result) case IMAGPART_EXPR: case REALPART_EXPR: case VIEW_CONVERT_EXPR: - case ADDR_EXPR: break; default: gcc_unreachable (); - } VEC_safe_push (vn_reference_op_s, heap, *result, &temp); - if (REFERENCE_CLASS_P (ref) || TREE_CODE (ref) == ADDR_EXPR) + if (REFERENCE_CLASS_P (ref) + || (TREE_CODE (ref) == ADDR_EXPR + && !is_gimple_min_invariant (ref))) ref = TREE_OPERAND (ref, 0); else ref = NULL_TREE; @@ -677,7 +684,6 @@ copy_reference_ops_from_call (gimple call, VEC(vn_reference_op_s, heap) **result) { vn_reference_op_s temp; - tree callfn; unsigned i; /* Copy the call_expr opcode, type, function being called, and @@ -685,33 +691,15 @@ copy_reference_ops_from_call (gimple call, memset (&temp, 0, sizeof (temp)); temp.type = gimple_call_return_type (call); temp.opcode = CALL_EXPR; + temp.op0 = gimple_call_fn (call); VEC_safe_push (vn_reference_op_s, heap, *result, &temp); - /* FIXME tuples - We make no attempt to simplify the called function because - the typical &FUNCTION_DECL form is also used in function pointer - cases that become constant. If we simplify the original to - FUNCTION_DECL but not the function pointer case (which can - happen because we have no fold functions that operate on - vn_reference_t), we will claim they are not equivalent. - - An example of this behavior can be see if CALL_EXPR_FN below is - replaced with get_callee_fndecl and gcc.dg/tree-ssa/ssa-pre-13.c - is compiled. */ - callfn = gimple_call_fn (call); - temp.type = TREE_TYPE (callfn); - temp.opcode = TREE_CODE (callfn); - temp.op0 = callfn; - VEC_safe_push (vn_reference_op_s, heap, *result, &temp); - + /* Copy the call arguments. As they can be references as well, + just chain them together. */ for (i = 0; i < gimple_call_num_args (call); ++i) { tree callarg = gimple_call_arg (call, i); - memset (&temp, 0, sizeof (temp)); - temp.type = TREE_TYPE (callarg); - temp.opcode = TREE_CODE (callarg); - temp.op0 = callarg; - VEC_safe_push (vn_reference_op_s, heap, *result, &temp); + copy_reference_ops_from_ref (callarg, result); } return; } |