diff options
author | ygribov <ygribov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-07-21 19:48:51 +0000 |
---|---|---|
committer | ygribov <ygribov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-07-21 19:48:51 +0000 |
commit | 322f1ba9870da39ac02bcce3d6981ef564572af5 (patch) | |
tree | d8eef4564991b0292b0db768be536f9bd4d883cd /gcc/ipa-visibility.c | |
parent | 0091498ce888398014dac43f204cdfb80bb77564 (diff) | |
download | gcc-322f1ba9870da39ac02bcce3d6981ef564572af5.tar.gz |
2017-07-21 Yury Gribov <tetra2005@gmail.com>
PR middle-end/56727
* ipa-visibility (function_and_variable_visibility): Convert
recursive PLT call to direct call if appropriate.
* gcc.dg/pr56727-1.c: New test.
* gcc.dg/pr56727-2.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@250442 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-visibility.c')
-rw-r--r-- | gcc/ipa-visibility.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c index 17186e9d2e6..21321703dbb 100644 --- a/gcc/ipa-visibility.c +++ b/gcc/ipa-visibility.c @@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "calls.h" #include "varasm.h" +#include "ipa-utils.h" /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */ @@ -617,6 +618,36 @@ function_and_variable_visibility (bool whole_program) /* All aliases should be procssed at this point. */ gcc_checking_assert (!alias_pairs || !alias_pairs->length ()); + FOR_EACH_DEFINED_FUNCTION (node) + { + if (node->get_availability () != AVAIL_INTERPOSABLE + || DECL_EXTERNAL (node->decl) + || node->has_aliases_p ()) + continue; + + cgraph_node *alias = 0; + for (cgraph_edge *e = node->callees; e; e = e->next_callee) + { + /* Recursive function calls usually can't be interposed. */ + + if (!e->recursive_p ()) + continue; + + if (!alias) + { + alias = dyn_cast<cgraph_node *> (node->noninterposable_alias ()); + gcc_assert (alias && alias != node); + } + + e->redirect_callee (alias); + if (gimple_has_body_p (e->caller->decl)) + { + push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl)); + e->redirect_call_stmt_to_callee (); + pop_cfun (); + } + } + } FOR_EACH_FUNCTION (node) { int flags = flags_from_decl_or_type (node->decl); |