diff options
author | Martin Liska <mliska@suse.cz> | 2015-03-03 10:26:20 +0100 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2015-03-03 09:26:20 +0000 |
commit | 17d1bf760f8fda0023d5074de0a2b2929e27c480 (patch) | |
tree | 95f961e1350a2d19eb23ce29ab324e11f8dee391 /gcc | |
parent | bd31fe14d2dfb4b12a82d9a223853ff2228a6523 (diff) | |
download | gcc-17d1bf760f8fda0023d5074de0a2b2929e27c480.zip gcc-17d1bf760f8fda0023d5074de0a2b2929e27c480.tar.gz gcc-17d1bf760f8fda0023d5074de0a2b2929e27c480.tar.bz2 |
re PR target/65263 (ICE (error: unrecognizable insn / in insn_min_length, at config/rs6000/rs6000.md) on powerpc64le-linux-gnu)
Fix PR ipa/65263.
PR ipa/65263
* cgraph.c (cgraph_node::has_thunk_p): New function.
* cgraph.h (cgraph_node::has_thunk_p: Likewise.
* ipa-icf.c (redirect_all_callers): Do not redirect thunks.
(sem_function::merge): Assert is changed.
* g++.dg/ipa/pr65263.C: New test.
Co-Authored-By: Jan Hubicka <hubicka@ucw.cz>
From-SVN: r221134
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cgraph.c | 12 | ||||
-rw-r--r-- | gcc/cgraph.h | 3 | ||||
-rw-r--r-- | gcc/ipa-icf.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr65263.C | 49 |
6 files changed, 100 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7d8cf78..5e11a0f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,13 @@ 2015-03-03 Martin Liska <mliska@suse.cz> + Jan Hubicka <hubicka@ucw.cz> + + PR ipa/65263 + * cgraph.c (cgraph_node::has_thunk_p): New function. + * cgraph.h (cgraph_node::has_thunk_p: Likewise. + * ipa-icf.c (redirect_all_callers): Do not redirect thunks. + (sem_function::merge): Assert is changed. + +2015-03-03 Martin Liska <mliska@suse.cz> Martin Jambor <mjambor@suse.cz> PR ipa/65087 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 5555439..9bae35e 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -3325,4 +3325,16 @@ cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *, } return false; } + +/* Return true if NODE has thunk. */ + +bool +cgraph_node::has_thunk_p (cgraph_node *node, void *) +{ + for (cgraph_edge *e = node->callers; e; e = e->next_caller) + if (e->caller->thunk.thunk_p) + return true; + return false; +} + #include "gt-cgraph.h" diff --git a/gcc/cgraph.h b/gcc/cgraph.h index ff437cf..82519fa 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1204,6 +1204,9 @@ public: with (not necessarily cgraph_node (DECL). */ static cgraph_node *create_alias (tree alias, tree target); + /* Return true if NODE has thunk. */ + static bool has_thunk_p (cgraph_node *node, void *); + cgraph_edge *callees; cgraph_edge *callers; /* List of edges representing indirect calls with a yet undetermined diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 9cdd73e..4832618 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -697,12 +697,22 @@ redirect_all_callers (cgraph_node *n, cgraph_node *to) { int nredirected = 0; ipa_ref *ref; + cgraph_edge *e = n->callers; - while (n->callers) + while (e) { - cgraph_edge *e = n->callers; - e->redirect_callee (to); - nredirected++; + /* Redirecting thunks to interposable symbols or symbols in other sections + may not be supported by target output code. Play safe for now and + punt on redirection. */ + if (!e->caller->thunk.thunk_p) + { + struct cgraph_edge *nexte = e->next_caller; + e->redirect_callee (to); + e = nexte; + nredirected++; + } + else + e = e->next_callee; } for (unsigned i = 0; n->iterate_direct_aliases (i, ref);) { @@ -717,6 +727,8 @@ redirect_all_callers (cgraph_node *n, cgraph_node *to) { nredirected += redirect_all_callers (n_alias, to); if (n_alias->can_remove_if_no_direct_calls_p () + && !n_alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p, + NULL, true) && !n_alias->has_aliases_p ()) n_alias->remove (); } @@ -907,6 +919,8 @@ sem_function::merge (sem_item *alias_item) return false; } if (!create_wrapper + && !alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p, + NULL, true) && !alias->can_remove_if_no_direct_calls_p ()) { if (dump_file) @@ -975,7 +989,10 @@ sem_function::merge (sem_item *alias_item) if (dump_file) fprintf (dump_file, "Unified; Wrapper has been created.\n\n"); } - gcc_assert (alias->icf_merged || remove); + + /* It's possible that redirection can hit thunks that block + redirection opportunities. */ + gcc_assert (alias->icf_merged || remove || redirect_callers); original->icf_merged = true; /* Inform the inliner about cross-module merging. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4555c13..2b3cf0e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-03-03 Martin Liska <mliska@suse.cz> + Jan Hubicka <hubicka@ucw.cz> + + * g++.dg/ipa/pr65263.C: New test. + 2015-03-02 Jan Hubicka <hubicka@ucw.cz> PR ipa/65130 diff --git a/gcc/testsuite/g++.dg/ipa/pr65263.C b/gcc/testsuite/g++.dg/ipa/pr65263.C new file mode 100644 index 0000000..34459a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr65263.C @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -c -w" } */ + +template <class> class A; +template <class R> struct VirtualMatrice { + virtual bool m_fn1(int) const { return true; } + struct B { + A<R> x; + B(VirtualMatrice *p1, A<R> p2) : x(p2) { p1->m_fn1(0) ?: throw; } + }; + void operator*(A<R> p1) { B(this, p1); } + ~VirtualMatrice(); +} +; +template <class> class A { +public: + operator int *(); + A(int *, long); +}; + +class G : public A<int> { +public: + G(long); +}; +int typedef Complex; +template <class> class H : VirtualMatrice<int> {}; +template <class> class C; +template <> class C<int> : H<Complex>, VirtualMatrice<Complex> { + bool m_fn1(int) const { return true; } +}; +template <class K, class Mat> +void DoIdoAction(int, int, A<K> p3, A<K>, A<K>, A<K>, Mat, Mat &p8) { + p8 *p3; +} + +class D { + typedef int K; + class F { + int operator()() const; + }; +}; +int D::F::operator()() const { + VirtualMatrice<K> *a; + VirtualMatrice<K> b, &B = *a; + G c(0), g(1); + int d, e, f; + A<K> h(&g[f], 0), i(&g[e], 0), j(&g[d], 0); + DoIdoAction(0, 3, h, i, j, c, b, B); +} |