]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/35164 (Unable to coalesce ab SSA_NAMEs)
authorRichard Guenther <rguenther@suse.de>
Fri, 15 Feb 2008 15:24:19 +0000 (15:24 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 15 Feb 2008 15:24:19 +0000 (15:24 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr35164-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/pr35164-2.C [new file with mode: 0644]
gcc/tree-dfa.c
gcc/tree-flow.h
gcc/tree-ssa-forwprop.c

index a82c143d3883994430da97d3c8d7503701a9a9d0..b3075a692cc948dafdfca438bc996ac95b80e696 100644 (file)
@@ -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
index 26b41f89f603444ae462020c5401b8e63947b4a8..f5ec2dece8653972aa99df71756c9d647efe7e7f 100644 (file)
@@ -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 (file)
index 0000000..1704c22
--- /dev/null
@@ -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 (file)
index 0000000..463cad7
--- /dev/null
@@ -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 (...) {
+        }
+    }
+}
index f79df0bb2b83703ffa45a324b98efea3b83f76a5..346f6f3803cee4dec82d277870174d1caaae7424 100644 (file)
@@ -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;
+}
+
index adc2508b1c1904e60573863803e5e5d99854ec5b..286c60bce2038cb19174dbc02d021717801ebdbc 100644 (file)
@@ -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);
index 2da17c8827de46f5ceb2db9aaff476897caa6772..91bd6179dfa14114cebef3d8959c12dc2b17b133 100644 (file)
@@ -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;