aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-08-19 09:06:54 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-08-19 09:06:54 +0000
commit53f3815cc08c390d2aee47a252203d416304298c (patch)
treeb82321d60c8540d93282490a2395f56bf8a0f30e /gcc/tree-ssa-sccvn.c
parent5d59337297f9410a407e2e8e89f38ebbc9aa40df (diff)
downloadgcc-53f3815cc08c390d2aee47a252203d416304298c.zip
gcc-53f3815cc08c390d2aee47a252203d416304298c.tar.gz
gcc-53f3815cc08c390d2aee47a252203d416304298c.tar.bz2
re PR tree-optimization/35972 (load-PRE missed opportunities without SFTs)
2008-08-19 Richard Guenther <rguenther@suse.de> PR tree-optimization/35972 PR tree-optimization/23094 * tree-ssa-sccvn.h (vn_reference_lookup_pieces): Add maywalk parameter. * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Properly handle MISALIGNED_INDIRECT_REF. (get_ref_from_reference_ops): New helper. (vn_reference_lookup_pieces): Walk the use-def chain using the alias-oracle if requested. * tree-ssa-pre.c (phi_translate_1): Do reference lookup with walking the use-def chain. (compute_avail): But not here. (create_component_ref_by_pieces_1): Properly handle MISALIGNED_INDIRECT_REF. (do_regular_insertion): Handle fully redundant expressions after PHI-translation also for SSA_NAME values, not only constants. Correctly use edoubleprime for that. * gcc.dg/tree-ssa/ssa-pre-19.c: New testcase. * gcc.dg/autopar/reduc-1.c: Move constant initialized arrays to global memory. * gcc.dg/autopar/reduc-1char.c: Likewise. * gcc.dg/autopar/reduc-1short.c: Likewise. * gcc.dg/autopar/reduc-2.c: Likewise. * gcc.dg/autopar/reduc-2char.c: Likewise. * gcc.dg/autopar/reduc-2short.c: Likewise. * gcc.dg/autopar/reduc-3.c: Likewise. * gcc.dg/tree-ssa/ifc-20040816-1.c: Likewise. * gcc.dg/vect/costmodel/i386/costmodel-vect-reduc-1char.c: Likewise. * gcc.dg/vect/costmodel/x86_64/costmodel-vect-reduc-1char.c: Likewise. * gcc.dg/vect/fast-math-vect-reduc-5.c: Likewise. * gcc.dg/vect/fast-math-vect-reduc-7.c: Likewise. * gcc.dg/vect/no-trapping-math-2.c: Likewise. * gcc.dg/vect/no-trapping-math-vect-111.c: Likewise. * gcc.dg/vect/no-trapping-math-vect-ifcvt-11.c: Likewise. * gcc.dg/vect/no-trapping-math-vect-ifcvt-12.c: Likewise. * gcc.dg/vect/no-trapping-math-vect-ifcvt-13.c: Likewise. * gcc.dg/vect/no-trapping-math-vect-ifcvt-14.c: Likewise. * gcc.dg/vect/no-trapping-math-vect-ifcvt-15.c: Likewise. * gcc.dg/vect/no-vfa-vect-37.c: Likewise. * gcc.dg/vect/no-vfa-vect-depend-1.c: Likewise. * gcc.dg/vect/pr18400.c: Likewise. * gcc.dg/vect/slp-12b.c: Likewise. * gcc.dg/vect/slp-14.c: Likewise. * gcc.dg/vect/slp-7.c: Likewise. * gcc.dg/vect/slp-15.c: Likewise. * gcc.dg/vect/slp-16.c: Likewise. * gcc.dg/vect/slp-17.c: Likewise. * gcc.dg/vect/slp-24.c: Likewise. * gcc.dg/vect/slp-28.c: Likewise. * gcc.dg/vect/slp-3.c: Likewise. * gcc.dg/vect/slp-34.c: Likewise. * gcc.dg/vect/slp-6.c: Likewise. * gcc.dg/vect/slp-8.c: Likewise. * gcc.dg/vect/vect-107.c: Likewise. * gcc.dg/vect/vect-108.c: Likewise. * gcc.dg/vect/vect-11.c: Likewise. * gcc.dg/vect/vect-112.c: Likewise. * gcc.dg/vect/vect-115.c: Likewise. * gcc.dg/vect/vect-11a.c: Likewise. * gcc.dg/vect/vect-34.c: Likewise. * gcc.dg/vect/vect-9.c: Likewise. * gcc.dg/vect/vect-97.c: Likewise. * gcc.dg/vect/vect-align-1.c: Likewise. * gcc.dg/vect/vect-float-extend-1.c: Likewise. * gcc.dg/vect/vect-floatint-conversion-1.c: Likewise. * gcc.dg/vect/vect-ifcvt-16.c: Likewise. * gcc.dg/vect/vect-ifcvt-17.c: Likewise. * gcc.dg/vect/vect-ifcvt-2.c: Likewise. * gcc.dg/vect/vect-ifcvt-3.c: Likewise. * gcc.dg/vect/vect-ifcvt-4.c: Likewise. * gcc.dg/vect/vect-ifcvt-5.c: Likewise. * gcc.dg/vect/vect-ifcvt-6.c: Likewise. * gcc.dg/vect/vect-ifcvt-7.c: Likewise. * gcc.dg/vect/vect-intfloat-conversion-1.c: Likewise. * gcc.dg/vect/vect-intfloat-conversion-2.c: Likewise. * gcc.dg/vect/vect-intfloat-conversion-3.c: Likewise. * gcc.dg/vect/vect-intfloat-conversion-4a.c: Likewise. * gcc.dg/vect/vect-intfloat-conversion-4b.c: Likewise. * gcc.dg/vect/vect-multitypes-2.c: Likewise. * gcc.dg/vect/vect-multitypes-5.c: Likewise. * gcc.dg/vect/vect-reduc-1.c: Likewise. * gcc.dg/vect/vect-reduc-1char.c: Likewise. * gcc.dg/vect/vect-reduc-1short.c: Likewise. * gcc.dg/vect/vect-reduc-2.c: Likewise. * gcc.dg/vect/vect-reduc-3.c: Likewise. * gcc.dg/vect/vect-shift-1.c: Likewise. * gcc.dg/vect/vect-strided-float.c: Likewise. * gcc.dg/vect/vect-strided-store-u32-i2.c: Likewise. * gcc.dg/vect/wrapv-vect-reduc-2char.c: Likewise. * gcc.dg/vect/wrapv-vect-reduc-2short.c: Likewise. * gcc.dg/tree-ssa/gen-vect-11.c: Likewise. * gcc.dg/tree-ssa/gen-vect-11a.c: Likewise. * gcc.dg/tree-ssa/gen-vect-2.c: Likewise. * gcc.dg/vect/costmodel/ppc/costmodel-vect-76c.c: Likewise. From-SVN: r139226
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c114
1 files changed, 112 insertions, 2 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index f502440..26a65f1 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -595,11 +595,13 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
switch (temp.opcode)
{
case ALIGN_INDIRECT_REF:
- case MISALIGNED_INDIRECT_REF:
case INDIRECT_REF:
/* The only operand is the address, which gets its own
vn_reference_op_s structure. */
break;
+ case MISALIGNED_INDIRECT_REF:
+ temp.op0 = TREE_OPERAND (ref, 1);
+ break;
case BIT_FIELD_REF:
/* Record bits and position. */
temp.op0 = TREE_OPERAND (ref, 1);
@@ -676,6 +678,92 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
}
}
+/* Re-create a reference tree from the reference ops OPS.
+ Returns NULL_TREE if the ops were not handled.
+ This routine needs to be kept in sync with copy_reference_ops_from_ref. */
+
+static tree
+get_ref_from_reference_ops (VEC(vn_reference_op_s, heap) *ops)
+{
+ vn_reference_op_t op;
+ unsigned i;
+ tree ref, *op0_p = &ref;
+
+ for (i = 0; VEC_iterate (vn_reference_op_s, ops, i, op); ++i)
+ {
+ switch (op->opcode)
+ {
+ case CALL_EXPR:
+ return NULL_TREE;
+
+ case ALIGN_INDIRECT_REF:
+ case INDIRECT_REF:
+ *op0_p = build1 (op->opcode, op->type, NULL_TREE);
+ op0_p = &TREE_OPERAND (*op0_p, 0);
+ break;
+
+ case MISALIGNED_INDIRECT_REF:
+ *op0_p = build2 (MISALIGNED_INDIRECT_REF, op->type,
+ NULL_TREE, op->op0);
+ op0_p = &TREE_OPERAND (*op0_p, 0);
+ break;
+
+ case BIT_FIELD_REF:
+ *op0_p = build3 (BIT_FIELD_REF, op->type, NULL_TREE,
+ op->op0, op->op1);
+ op0_p = &TREE_OPERAND (*op0_p, 0);
+ break;
+
+ case COMPONENT_REF:
+ *op0_p = build3 (COMPONENT_REF, TREE_TYPE (op->op0), NULL_TREE,
+ op->op0, op->op1);
+ op0_p = &TREE_OPERAND (*op0_p, 0);
+ break;
+
+ case ARRAY_RANGE_REF:
+ case ARRAY_REF:
+ *op0_p = build4 (op->opcode, op->type, NULL_TREE,
+ op->op0, op->op1, op->op2);
+ op0_p = &TREE_OPERAND (*op0_p, 0);
+ break;
+
+ case STRING_CST:
+ case INTEGER_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
+ case REAL_CST:
+ case CONSTRUCTOR:
+ case VAR_DECL:
+ case PARM_DECL:
+ case CONST_DECL:
+ case RESULT_DECL:
+ case SSA_NAME:
+ *op0_p = op->op0;
+ break;
+
+ case ADDR_EXPR:
+ if (op->op0 != NULL_TREE)
+ {
+ gcc_assert (is_gimple_min_invariant (op->op0));
+ *op0_p = op->op0;
+ break;
+ }
+ /* Fallthrough. */
+ case IMAGPART_EXPR:
+ case REALPART_EXPR:
+ case VIEW_CONVERT_EXPR:
+ *op0_p = build1 (op->opcode, op->type, NULL_TREE);
+ op0_p = &TREE_OPERAND (*op0_p, 0);
+ break;
+
+ default:
+ return NULL_TREE;
+ }
+ }
+
+ return ref;
+}
+
/* Copy the operations present in load/store/call REF into RESULT, a vector of
vn_reference_op_s's. */
@@ -895,7 +983,7 @@ vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
tree
vn_reference_lookup_pieces (VEC (tree, gc) *vuses,
VEC (vn_reference_op_s, heap) *operands,
- vn_reference_t *vnresult)
+ vn_reference_t *vnresult, bool maywalk)
{
struct vn_reference_s vr1;
tree result;
@@ -907,6 +995,28 @@ vn_reference_lookup_pieces (VEC (tree, gc) *vuses,
vr1.hashcode = vn_reference_compute_hash (&vr1);
result = vn_reference_lookup_1 (&vr1, vnresult);
+ /* If there is a single defining statement for all virtual uses, we can
+ use that, following virtual use-def chains. */
+ if (!result
+ && maywalk
+ && vr1.vuses
+ && VEC_length (tree, vr1.vuses) >= 1)
+ {
+ tree ref = get_ref_from_reference_ops (operands);
+ gimple def_stmt;
+ if (ref
+ && (def_stmt = get_def_ref_stmt_vuses (ref, vr1.vuses))
+ && is_gimple_assign (def_stmt))
+ {
+ /* We are now at an aliasing definition for the vuses we want to
+ look up. Re-do the lookup with the vdefs for this stmt. */
+ vdefs_to_vec (def_stmt, &vuses);
+ vr1.vuses = valueize_vuses (vuses);
+ vr1.hashcode = vn_reference_compute_hash (&vr1);
+ result = vn_reference_lookup_1 (&vr1, vnresult);
+ }
+ }
+
return result;
}