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
This commit is contained in:
parent
bd31fe14d2
commit
17d1bf760f
|
@ -1,3 +1,12 @@
|
||||||
|
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>
|
2015-03-03 Martin Liska <mliska@suse.cz>
|
||||||
Martin Jambor <mjambor@suse.cz>
|
Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
|
12
gcc/cgraph.c
12
gcc/cgraph.c
|
@ -3325,4 +3325,16 @@ cgraph_node::call_for_symbol_and_aliases_1 (bool (*callback) (cgraph_node *,
|
||||||
}
|
}
|
||||||
return false;
|
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"
|
#include "gt-cgraph.h"
|
||||||
|
|
|
@ -1204,6 +1204,9 @@ public:
|
||||||
with (not necessarily cgraph_node (DECL). */
|
with (not necessarily cgraph_node (DECL). */
|
||||||
static cgraph_node *create_alias (tree alias, tree target);
|
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 *callees;
|
||||||
cgraph_edge *callers;
|
cgraph_edge *callers;
|
||||||
/* List of edges representing indirect calls with a yet undetermined
|
/* List of edges representing indirect calls with a yet undetermined
|
||||||
|
|
|
@ -697,12 +697,22 @@ redirect_all_callers (cgraph_node *n, cgraph_node *to)
|
||||||
{
|
{
|
||||||
int nredirected = 0;
|
int nredirected = 0;
|
||||||
ipa_ref *ref;
|
ipa_ref *ref;
|
||||||
|
cgraph_edge *e = n->callers;
|
||||||
|
|
||||||
while (n->callers)
|
while (e)
|
||||||
{
|
{
|
||||||
cgraph_edge *e = n->callers;
|
/* Redirecting thunks to interposable symbols or symbols in other sections
|
||||||
e->redirect_callee (to);
|
may not be supported by target output code. Play safe for now and
|
||||||
nredirected++;
|
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);)
|
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);
|
nredirected += redirect_all_callers (n_alias, to);
|
||||||
if (n_alias->can_remove_if_no_direct_calls_p ()
|
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->has_aliases_p ())
|
||||||
n_alias->remove ();
|
n_alias->remove ();
|
||||||
}
|
}
|
||||||
|
@ -907,6 +919,8 @@ sem_function::merge (sem_item *alias_item)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!create_wrapper
|
if (!create_wrapper
|
||||||
|
&& !alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
|
||||||
|
NULL, true)
|
||||||
&& !alias->can_remove_if_no_direct_calls_p ())
|
&& !alias->can_remove_if_no_direct_calls_p ())
|
||||||
{
|
{
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
|
@ -975,7 +989,10 @@ sem_function::merge (sem_item *alias_item)
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
fprintf (dump_file, "Unified; Wrapper has been created.\n\n");
|
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;
|
original->icf_merged = true;
|
||||||
|
|
||||||
/* Inform the inliner about cross-module merging. */
|
/* Inform the inliner about cross-module merging. */
|
||||||
|
|
|
@ -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>
|
2015-03-02 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
PR ipa/65130
|
PR ipa/65130
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue