diff options
author | Jan Hubicka <jh@suse.cz> | 2013-08-02 16:38:15 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-08-02 14:38:15 +0000 |
commit | af15184ab60cc2c2caf47964734c3e123bc04f7c (patch) | |
tree | 1cccd5c74a32da024ef7d68be27022345b749039 /gcc/ipa.c | |
parent | 01e54ef86f407385b0f2bb7afb5748f0db31bce8 (diff) | |
download | gcc-af15184ab60cc2c2caf47964734c3e123bc04f7c.zip gcc-af15184ab60cc2c2caf47964734c3e123bc04f7c.tar.gz gcc-af15184ab60cc2c2caf47964734c3e123bc04f7c.tar.bz2 |
cgraph.c (cgraph_function_body_availability): Do not check cgrpah flags.
* cgraph.c (cgraph_function_body_availability): Do not check cgrpah flags.
* cgraph.h (symtab_for_node_and_aliases, symtab_nonoverwritable_alias,
symtab_node_availability): Declare.
* ipa.c (can_replace_by_local_alias): New.
(function_and_variable_visibility): Use it.
* symtab.c (symtab_for_node_and_aliases, symtab_nonoverwritable_alias_1,
symtab_nonoverwritable_alias): New.
Co-Authored-By: Martin Liska <marxin.liska@gmail.com>
From-SVN: r201439
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r-- | gcc/ipa.c | 46 |
1 files changed, 45 insertions, 1 deletions
@@ -751,6 +751,21 @@ varpool_externally_visible_p (struct varpool_node *vnode) return false; } +/* Return true if reference to NODE can be replaced by a local alias. + Local aliases save dynamic linking overhead and enable more optimizations. + */ + +bool +can_replace_by_local_alias (symtab_node node) +{ + return (symtab_node_availability (node) > AVAIL_OVERWRITABLE + && !DECL_EXTERNAL (node->symbol.decl) + && (!DECL_ONE_ONLY (node->symbol.decl) + || node->symbol.resolution == LDPR_PREVAILING_DEF + || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY + || node->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)); +} + /* Mark visibility of all functions. A local function is one whose calls can occur only in the current @@ -872,7 +887,36 @@ function_and_variable_visibility (bool whole_program) } } FOR_EACH_DEFINED_FUNCTION (node) - node->local.local = cgraph_local_node_p (node); + { + node->local.local = cgraph_local_node_p (node); + + /* If we know that function can not be overwritten by a different semantics + and moreover its section can not be discarded, replace all direct calls + by calls to an nonoverwritable alias. This make dynamic linking + cheaper and enable more optimization. + + TODO: We can also update virtual tables. */ + if (node->callers && can_replace_by_local_alias ((symtab_node)node)) + { + struct cgraph_node *alias = cgraph (symtab_nonoverwritable_alias ((symtab_node) node)); + + if (alias != node) + { + while (node->callers) + { + struct cgraph_edge *e = node->callers; + + cgraph_redirect_edge_callee (e, alias); + if (!flag_wpa) + { + push_cfun (DECL_STRUCT_FUNCTION (e->caller->symbol.decl)); + cgraph_redirect_edge_call_stmt_to_callee (e); + pop_cfun (); + } + } + } + } + } FOR_EACH_VARIABLE (vnode) { /* weak flag makes no sense on local variables. */ |