Message ID | 20150115231512.GA26595@kam.mff.cuni.cz |
---|---|
State | New |
Headers | show |
On 2015.01.16 at 00:15 +0100, Jan Hubicka wrote: > Hi, > can_remove_node_now_p assumes that the node in question has no direct calls, this > however is not checked in inline_call that leads to alias to be removed from > comdat group while it should not. > > Bootstrapped/regtested x86_64-linux, comitted. Here's a testcase for this issue. OK for trunk? 2015-01-16 Markus Trippelsdorf <markus@trippelsdorf.de> PR ipa/64163 PR ipa/64612 * g++.dg/ipa/pr64612.C: New test. /* { dg-do compile } */ /* { dg-options "-fPIC -O3 -std=c++11" } */ /* { dg-final { scan-assembler "_ZN5QListI7QStringED1Ev" } } */ class A { public: bool deref (); }; class QString; struct B { A ref; }; template <typename> class QList { B d; public: ~QList (); class const_iterator { }; const_iterator constBegin (); void clear (); void dealloc (); }; template <typename T> QList<T>::~QList () { if (d.ref.deref ()) dealloc (); } template <typename T> void QList<T>::clear () { QList (); } class A1 : public QList<QString> { }; class B1 { public: B1 (A1); }; struct F { void addMatch (const QString &&); A1 m_matchingMimeTypes; }; class G { A1 matchingGlobs (const QString &) const; }; void F::addMatch (const QString &&) { m_matchingMimeTypes.clear (); } A1 G::matchingGlobs (const QString &) const { A1 a; for (B1 b (a);;) ; }
On Fri, Jan 16, 2015 at 9:34 AM, Markus Trippelsdorf <markus@trippelsdorf.de> wrote: > On 2015.01.16 at 00:15 +0100, Jan Hubicka wrote: >> Hi, >> can_remove_node_now_p assumes that the node in question has no direct calls, this >> however is not checked in inline_call that leads to alias to be removed from >> comdat group while it should not. >> >> Bootstrapped/regtested x86_64-linux, comitted. > > Here's a testcase for this issue. OK for trunk? Ok. Thanks, Richard. > 2015-01-16 Markus Trippelsdorf <markus@trippelsdorf.de> > > PR ipa/64163 > PR ipa/64612 > * g++.dg/ipa/pr64612.C: New test. > > /* { dg-do compile } */ > /* { dg-options "-fPIC -O3 -std=c++11" } */ > /* { dg-final { scan-assembler "_ZN5QListI7QStringED1Ev" } } */ > > class A > { > public: > bool deref (); > }; > class QString; > struct B > { > A ref; > }; > template <typename> class QList > { > B d; > public: > ~QList (); > class const_iterator > { > }; > const_iterator constBegin (); > void clear (); > void dealloc (); > }; > template <typename T> QList<T>::~QList () > { > if (d.ref.deref ()) > dealloc (); > } > template <typename T> > void > QList<T>::clear () > { > QList (); > } > class A1 : public QList<QString> > { > }; > class B1 > { > public: > B1 (A1); > }; > struct F > { > void addMatch (const QString &&); > A1 m_matchingMimeTypes; > }; > class G > { > A1 matchingGlobs (const QString &) const; > }; > void > F::addMatch (const QString &&) > { > m_matchingMimeTypes.clear (); > } > A1 > G::matchingGlobs (const QString &) const > { > A1 a; > for (B1 b (a);;) > ; > } > > -- > Markus
On 2015.01.16 at 12:03 +0100, Richard Biener wrote: > On Fri, Jan 16, 2015 at 9:34 AM, Markus Trippelsdorf > <markus@trippelsdorf.de> wrote: > > On 2015.01.16 at 00:15 +0100, Jan Hubicka wrote: > >> Hi, > >> can_remove_node_now_p assumes that the node in question has no direct calls, this > >> however is not checked in inline_call that leads to alias to be removed from > >> comdat group while it should not. > >> > >> Bootstrapped/regtested x86_64-linux, comitted. > > > > Here's a testcase for this issue. OK for trunk? > > Ok. Thanks, committed. I dropped the -fPIC flag, because it isn't necessary.
Index: ipa-inline-transform.c =================================================================== --- ipa-inline-transform.c (revision 219674) +++ ipa-inline-transform.c (working copy) @@ -139,7 +139,7 @@ can_remove_node_now_p (struct cgraph_nod /* When we see same comdat group, we need to be sure that all items can be removed. */ - if (!node->same_comdat_group) + if (!node->same_comdat_group || !node->externally_visible) return true; for (next = dyn_cast<cgraph_node *> (node->same_comdat_group); next != node; next = dyn_cast<cgraph_node *> (next->same_comdat_group)) @@ -310,7 +310,8 @@ inline_call (struct cgraph_edge *e, bool while (alias && alias != callee) { if (!alias->callers - && can_remove_node_now_p (alias, e)) + && can_remove_node_now_p (alias, + !e->next_caller && !e->prev_caller ? e : NULL)) { next_alias = alias->get_alias_target (); alias->remove ();