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
This commit is contained in:
Richard Guenther 2008-02-15 15:24:19 +00:00 committed by Richard Biener
parent 508515b027
commit 2e58df6ecf
7 changed files with 134 additions and 1 deletions

View 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

View 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

View File

@ -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);
}
}

View File

@ -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 (...) {
}
}
}

View 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;
}

View 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);

View 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;