From dafc951101fe6d8feeffecee7ac2e41cad1b7fe2 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 20 Apr 2011 13:11:06 +0000 Subject: [PATCH] re PR rtl-optimization/48695 (Runtime with an array of std::vectors) 2011-04-20 Richard Guenther PR middle-end/48695 * tree-ssa-alias.c (aliasing_component_refs_p): Compute base objects and types here. Adjust for their offset before comparing. * g++.dg/torture/pr48695.C: New testcase. From-SVN: r172768 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/torture/pr48695.C | 38 ++++++++++++++++++++++++++++++++++ gcc/tree-ssa-alias.c | 29 +++++++++++++++++++------- 4 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr48695.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ff852b..da88769 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-04-20 Richard Guenther + + PR middle-end/48695 + * tree-ssa-alias.c (aliasing_component_refs_p): Compute base + objects and types here. Adjust for their offset before + comparing. + 2011-04-20 Richard Sandiford * doc/md.texi, optabs.h, genopinit.c, internal-fn.def diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ac3e350..a4b42d9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-04-20 Richard Guenther + + PR middle-end/48695 + * g++.dg/torture/pr48695.C: New testcase. + 2011-04-20 Georg-Johann Lay * gcc.dg/pr42629.c: Add dg-require-effective-target int32plus diff --git a/gcc/testsuite/g++.dg/torture/pr48695.C b/gcc/testsuite/g++.dg/torture/pr48695.C new file mode 100644 index 0000000..44e6c77 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr48695.C @@ -0,0 +1,38 @@ +// { dg-do run } + +typedef __SIZE_TYPE__ size_t; + +inline void *operator new (size_t, void *__p) throw() { return __p; } + +struct _Vector_impl +{ + int *_M_start; + int *_M_finish; + _Vector_impl () :_M_start (0), _M_finish (0) {} +}; + +struct vector +{ + _Vector_impl _M_impl; + int *_M_allocate (size_t __n) + { + return __n != 0 ? new int[__n] : 0; + } + void push_back () + { + new (this->_M_impl._M_finish) int (); + this->_M_impl._M_finish = + this->_M_allocate (this->_M_impl._M_finish - this->_M_impl._M_start) + 1; + } +}; + +int +main () +{ + for (int i = 0; i <= 1; i++) + for (int j = 0; j <= 1; j++) + { + vector a[2]; + a[i].push_back (); + } +} diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 67ba8f1..a77c803 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -593,11 +593,11 @@ same_type_for_tbaa (tree type1, tree type2) are the respective alias sets. */ static bool -aliasing_component_refs_p (tree ref1, tree type1, +aliasing_component_refs_p (tree ref1, alias_set_type ref1_alias_set, alias_set_type base1_alias_set, HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1, - tree ref2, tree type2, + tree ref2, alias_set_type ref2_alias_set, alias_set_type base2_alias_set, HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2, @@ -609,9 +609,21 @@ aliasing_component_refs_p (tree ref1, tree type1, struct A { int i; int j; } *q; struct B { struct A a; int k; } *p; disambiguating q->i and p->a.j. */ + tree base1, base2; + tree type1, type2; tree *refp; int same_p; + /* Choose bases and base types to search for. */ + base1 = ref1; + while (handled_component_p (base1)) + base1 = TREE_OPERAND (base1, 0); + type1 = TREE_TYPE (base1); + base2 = ref2; + while (handled_component_p (base2)) + base2 = TREE_OPERAND (base2, 0); + type2 = TREE_TYPE (base2); + /* Now search for the type1 in the access path of ref2. This would be a common base for doing offset based disambiguation on. */ refp = &ref2; @@ -627,6 +639,8 @@ aliasing_component_refs_p (tree ref1, tree type1, HOST_WIDE_INT offadj, sztmp, msztmp; get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp); offset2 -= offadj; + get_ref_base_and_extent (base1, &offadj, &sztmp, &msztmp); + offset1 -= offadj; return ranges_overlap_p (offset1, max_size1, offset2, max_size2); } /* If we didn't find a common base, try the other way around. */ @@ -643,6 +657,8 @@ aliasing_component_refs_p (tree ref1, tree type1, HOST_WIDE_INT offadj, sztmp, msztmp; get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp); offset1 -= offadj; + get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp); + offset2 -= offadj; return ranges_overlap_p (offset1, max_size1, offset2, max_size2); } @@ -804,11 +820,10 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, && TREE_CODE (base1) != TARGET_MEM_REF && (TREE_CODE (base1) != MEM_REF || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1)) - return aliasing_component_refs_p (ref1, TREE_TYPE (ptrtype1), + return aliasing_component_refs_p (ref1, ref1_alias_set, base1_alias_set, offset1, max_size1, - ref2, TREE_TYPE - (reference_alias_ptr_type (ref2)), + ref2, ref2_alias_set, base2_alias_set, offset2, max_size2, true); @@ -951,10 +966,10 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1) && (TREE_CODE (base2) != MEM_REF || same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1)) - return aliasing_component_refs_p (ref1, TREE_TYPE (ptrtype1), + return aliasing_component_refs_p (ref1, ref1_alias_set, base1_alias_set, offset1, max_size1, - ref2, TREE_TYPE (ptrtype2), + ref2, ref2_alias_set, base2_alias_set, offset2, max_size2, false); -- 2.7.4