diff options
author | Martin Jambor <mjambor@suse.cz> | 2020-04-16 19:21:02 +0200 |
---|---|---|
committer | Martin Jambor <mjambor@suse.cz> | 2020-04-16 19:21:02 +0200 |
commit | 7123347c8b44571811c4b58506b06fb09969bccb (patch) | |
tree | ddf5d23a57ce231aef99ac668163fa8a8baddcde /gcc/ipa-inline-transform.c | |
parent | 26bebf576ddcdcfb596f07e8c2896f17c48516e7 (diff) | |
download | gcc-7123347c8b44571811c4b58506b06fb09969bccb.zip gcc-7123347c8b44571811c4b58506b06fb09969bccb.tar.gz gcc-7123347c8b44571811c4b58506b06fb09969bccb.tar.bz2 |
ipa: Make call redirection detect already adjusted calls (PR 93621)
PR 93621 testcase makes redirect_call_stmt_to_callee wrongly assume
that a call statement needs redirecting but then rightly fails an
assert ensuring the call statement parameters have not already been
adjusted because they were already created adjusted as part of thunk
expansion.
The test fails because the decl in the call call statement is
different than the decl of the callee, because the latter was created
in save_inline_function_body. This patch adds a way to link these two
and detect the situation in redirect_call_stmt_to_callee.
2020-04-16 Martin Jambor <mjambor@suse.cz>
PR ipa/93621
* ipa-inline.h (ipa_saved_clone_sources): Declare.
* ipa-inline-transform.c (ipa_saved_clone_sources): New variable.
(save_inline_function_body): Link the new body holder with the
previous one.
* cgraph.c: Include ipa-inline.h.
(cgraph_edge::redirect_call_stmt_to_callee): Try to find the decl from
the statement in ipa_saved_clone_sources.
* cgraphunit.c: Include ipa-inline.h.
(expand_all_functions): Free ipa_saved_clone_sources.
testsuite/
* g++.dg/ipa/pr93621.C: New test.
Diffstat (limited to 'gcc/ipa-inline-transform.c')
-rw-r--r-- | gcc/ipa-inline-transform.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index eed992d..be60bbc 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -531,6 +531,11 @@ inline_call (struct cgraph_edge *e, bool update_original, return new_edges_found; } +/* For each node that was made the holder of function body by + save_inline_function_body, this summary contains pointer to the previous + holder of the body. */ + +function_summary <tree *> *ipa_saved_clone_sources; /* Copy function body of NODE and redirect all inline clones to it. This is done before inline plan is applied to NODE when there are @@ -588,6 +593,20 @@ save_inline_function_body (struct cgraph_node *node) first_clone->next_sibling_clone = NULL; gcc_assert (!first_clone->prev_sibling_clone); } + + tree prev_body_holder = node->decl; + if (!ipa_saved_clone_sources) + ipa_saved_clone_sources = new function_summary <tree *> (symtab); + else + { + tree *p = ipa_saved_clone_sources->get (node); + if (p) + { + prev_body_holder = *p; + gcc_assert (prev_body_holder); + } + } + *ipa_saved_clone_sources->get_create (first_clone) = prev_body_holder; first_clone->clone_of = NULL; /* Now node in question has no clones. */ |