aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-02-15 15:24:19 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-02-15 15:24:19 +0000
commit2e58df6ecf3d060e3a8bd95f898baf89f733e1f5 (patch)
tree84bac3426747a9ff72e762dc1ff06bfc9e4f61f7
parent508515b0277f2adadc610acb2dd14f769ba992ff (diff)
downloadgcc-2e58df6ecf3d060e3a8bd95f898baf89f733e1f5.zip
gcc-2e58df6ecf3d060e3a8bd95f898baf89f733e1f5.tar.gz
gcc-2e58df6ecf3d060e3a8bd95f898baf89f733e1f5.tar.bz2
re PR tree-optimization/35164 (Unable to coalesce ab SSA_NAMEs)
2008-02-15 Richard Guenther <rguenther@suse.de> Zdenek Dvorak <ook@ucw.cz> PR tree-optimization/35164 * tree-flow.h (stmt_references_abnormal_ssa_name): Declare. * tree-dfa.c (stmt_references_abnormal_ssa_name): New function. * tree-ssa-forwprop.c (tree_ssa_forward_propagate_single_use_vars): Only propagate addresses which do not have abnormal SSA_NAMEs in their operands. * g++.dg/torture/pr35164-1.C: New testcase. * g++.dg/torture/pr35164-2.C: Likewise. Co-Authored-By: Zdenek Dvorak <ook@ucw.cz> From-SVN: r132345
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/torture/pr35164-1.C69
-rw-r--r--gcc/testsuite/g++.dg/torture/pr35164-2.C27
-rw-r--r--gcc/tree-dfa.c18
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-ssa-forwprop.c3
7 files changed, 134 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a82c143..b3075a6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2008-02-15 Richard Guenther <rguenther@suse.de>
+ Zdenek Dvorak <ook@ucw.cz>
+
+ PR tree-optimization/35164
+ * tree-flow.h (stmt_references_abnormal_ssa_name): Declare.
+ * tree-dfa.c (stmt_references_abnormal_ssa_name): New function.
+ * tree-ssa-forwprop.c (tree_ssa_forward_propagate_single_use_vars):
+ Only propagate addresses which do not have abnormal SSA_NAMEs
+ in their operands.
+
2008-02-15 Joseph Myers <joseph@codesourcery.com>
PR target/35088
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 26b41f8..f5ec2de 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2008-02-15 Richard Guenther <rguenther@suse.de>
+ Zdenek Dvorak <ook@ucw.cz>
+
+ PR tree-optimization/35164
+ * g++.dg/torture/pr35164-1.C: New testcase.
+ * g++.dg/torture/pr35164-2.C: Likewise.
+
2008-02-15 Dominique d'Humieres <dominiq@lps.ens.fr>
PR testsuite/35119
diff --git a/gcc/testsuite/g++.dg/torture/pr35164-1.C b/gcc/testsuite/g++.dg/torture/pr35164-1.C
new file mode 100644
index 0000000..1704c22
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr35164-1.C
@@ -0,0 +1,69 @@
+typedef __SIZE_TYPE__ size_t;
+template<typename _Iterator, typename _Container> class __normal_iterator {
+public:
+ const _Iterator& base() const;
+};
+template<typename _BI1, typename _BI2> inline
+void copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) {
+ while (__first != __last) *--__result = *--__last;
+}
+template<typename _Tp> struct _Vector_base {
+ struct _Vector_impl { _Tp* _M_finish; };
+ _Vector_impl _M_impl;
+};
+template<typename _Tp > class vector : protected _Vector_base<_Tp> {
+ typedef vector<_Tp> vector_type;
+ typedef _Tp * pointer;
+ typedef _Tp & reference;
+ typedef __normal_iterator<pointer, vector_type> iterator;
+ typedef size_t size_type;
+public:
+ iterator end();
+ void resize(size_type __new_size) { insert(end(), __new_size); }
+ reference operator[](size_type __n);
+ void insert(iterator __position, size_type __n)
+ {
+ pointer __old_finish(this->_M_impl._M_finish);
+ copy_backward(__position.base(), __old_finish - __n, __old_finish);
+ }
+};
+struct A {
+ virtual ~A ();
+ void incRef ();
+ void decRef ();
+};
+struct C : public A {
+ static C *alloc ();
+};
+template <class T> struct B {
+ B () : ptr (T::alloc ()) { }
+ B (T *a_ptr) : ptr (a_ptr) { }
+ ~B () { decRef (); }
+ B& operator= (const B<T>& a) { if (a.get () != this->get ()) { decRef ();
+incRef (); } }
+ template<class U> operator B<U> () const { return B<U> (ptr); }
+ T* operator-> () const { }
+ T* get () const { return ptr; }
+ void decRef () const { if (ptr != 0) ptr->decRef (); }
+ void incRef () const { if (ptr != 0) ptr->incRef (); }
+ T *ptr;
+};
+struct D : public C {
+ template <class T> inline void foo (const B<T> & x) { d.resize (1); d[0] = x;
+}
+ vector<B <C> > d;
+};
+struct E : public C {
+ static E *alloc ();
+};
+struct F : public D {
+ static F *alloc ();
+};
+void foo (vector<B<D> > & x) {
+ for (int i = 0; i < 2; ++i)
+ {
+ B<F> l;
+ B<E> m;
+ l->foo (m);
+ }
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr35164-2.C b/gcc/testsuite/g++.dg/torture/pr35164-2.C
new file mode 100644
index 0000000..463cad7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr35164-2.C
@@ -0,0 +1,27 @@
+struct __shared_count {
+ __shared_count() { _M_pi = new int; }
+ int * _M_pi;
+};
+template<typename _Tp>
+class __shared_ptr {
+public:
+ __shared_ptr(_Tp* __p);
+ void reset(int * __p) {
+ __shared_ptr(__p).swap(*this);
+ }
+ void swap(__shared_ptr<_Tp>& __other) {
+ __other._M_refcount._M_pi = _M_refcount._M_pi;
+ }
+ __shared_count _M_refcount;
+};
+template<typename _Tp> class shared_ptr : public __shared_ptr<_Tp> {};
+int main() {
+ for (shared_ptr<int> *iter;;)
+ {
+ try {
+ (iter++)->reset(new int);
+ }
+ catch (...) {
+ }
+ }
+}
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index f79df0b..346f6f3 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -1028,3 +1028,21 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
return exp;
}
+/* Returns true if STMT references an SSA_NAME that has
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI set, otherwise false. */
+
+bool
+stmt_references_abnormal_ssa_name (tree stmt)
+{
+ ssa_op_iter oi;
+ use_operand_p use_p;
+
+ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE)
+ {
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (use_p)))
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index adc2508..286c60b 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -822,6 +822,7 @@ extern void find_new_referenced_vars (tree *);
extern tree make_rename_temp (tree, const char *);
extern void set_default_def (tree, tree);
extern tree gimple_default_def (struct function *, tree);
+extern bool stmt_references_abnormal_ssa_name (tree);
/* In tree-phinodes.c */
extern void reserve_phi_args_for_new_edge (basic_block);
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 2da17c8..91bd617 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -968,7 +968,8 @@ tree_ssa_forward_propagate_single_use_vars (void)
&& types_compatible_p (TREE_TYPE (TREE_TYPE (TREE_OPERAND (rhs, 0))),
TREE_TYPE (TREE_TYPE (rhs)))))
{
- if (forward_propagate_addr_expr (lhs, rhs))
+ if (!stmt_references_abnormal_ssa_name (stmt)
+ && forward_propagate_addr_expr (lhs, rhs))
{
release_defs (stmt);
todoflags |= TODO_remove_unused_locals;