diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2016-05-04 18:36:51 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2016-05-04 16:36:51 +0000 |
commit | 6b715bf6d991249181ce532442fa5513e137f708 (patch) | |
tree | 9eaf587465ab186e64c5890827bfe771bf2b2f5c /gcc/ipa-pure-const.c | |
parent | deef71132774618d06d571e935d10753f92d8ad9 (diff) | |
download | gcc-6b715bf6d991249181ce532442fa5513e137f708.zip gcc-6b715bf6d991249181ce532442fa5513e137f708.tar.gz gcc-6b715bf6d991249181ce532442fa5513e137f708.tar.bz2 |
cgraph.c (cgraph_node::call_for_symbol_thunks_and_aliases): Check availability on NODE, too.
* cgraph.c (cgraph_node::call_for_symbol_thunks_and_aliases):
Check availability on NODE, too.
* cgraph.h (symtab_node::call_for_symbol_and_aliases): Likewise.
(cgraph_node::call_for_symbol_and_aliases): Likewise.
(varpool_node::call_for_symbol_and_aliase): Likewise.
* ipa-pure-const.c (add_new_function): Analyze all bodies.
(propagate_pure_const): Propagate across interposable functions, too.
(skip_function_for_local_pure_const): Do not skip interposable bodies
with aliases.
(pass_local_pure_const::execute): Update.
* gcc.dg/ipa/pure-const-3.c: New testcase.
From-SVN: r235887
Diffstat (limited to 'gcc/ipa-pure-const.c')
-rw-r--r-- | gcc/ipa-pure-const.c | 102 |
1 files changed, 52 insertions, 50 deletions
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 63fbf581..ba76275 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -927,8 +927,6 @@ end: static void add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) { - if (node->get_availability () < AVAIL_INTERPOSABLE) - return; /* There are some shared nodes, in particular the initializers on static declarations. We do not need to scan them more than once since all we would be interested in are the addressof @@ -1222,6 +1220,7 @@ propagate_pure_const (void) int i; struct ipa_dfs_info * w_info; bool remove_p = false; + bool has_cdtor; order_pos = ipa_reduced_postorder (order, true, false, ignore_edge_for_pure_const); @@ -1274,26 +1273,6 @@ propagate_pure_const (void) if (pure_const_state == IPA_NEITHER) break; - /* For interposable nodes we can not assume anything. - FIXME: It should be safe to remove this conditional and allow - interposable functions with non-interposable aliases next - stage 1. */ - if (w->get_availability () == AVAIL_INTERPOSABLE) - { - worse_state (&pure_const_state, &looping, - w_l->state_previously_known, - w_l->looping_previously_known, - NULL, NULL); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, - " Interposable. state %s looping %i\n", - pure_const_names[w_l->state_previously_known], - w_l->looping_previously_known); - } - break; - } - count++; /* We consider recursive cycles as possibly infinite. @@ -1506,9 +1485,22 @@ propagate_pure_const (void) this_looping ? "looping " : "", w->name ()); } - remove_p |= w->call_for_symbol_and_aliases (cdtor_p, - NULL, true); - w->set_const_flag (true, this_looping); + /* Turning constructor or destructor to non-looping const/pure + enables us to possibly remove the function completely. */ + if (this_looping) + has_cdtor = false; + else + has_cdtor = w->call_for_symbol_and_aliases (cdtor_p, + NULL, true); + if (w->set_const_flag (true, this_looping)) + { + if (dump_file) + fprintf (dump_file, + "Declaration updated to be %sconst: %s\n", + this_looping ? "looping " : "", + w->name ()); + remove_p |= has_cdtor; + } break; case IPA_PURE: @@ -1520,9 +1512,20 @@ propagate_pure_const (void) this_looping ? "looping " : "", w->name ()); } - remove_p |= w->call_for_symbol_and_aliases (cdtor_p, - NULL, true); - w->set_pure_flag (true, this_looping); + if (this_looping) + has_cdtor = false; + else + has_cdtor = w->call_for_symbol_and_aliases (cdtor_p, + NULL, true); + if (w->set_pure_flag (true, this_looping)) + { + if (dump_file) + fprintf (dump_file, + "Declaration updated to be %spure: %s\n", + this_looping ? "looping " : "", + w->name ()); + remove_p |= has_cdtor; + } break; default: @@ -1723,11 +1726,14 @@ skip_function_for_local_pure_const (struct cgraph_node *node) fprintf (dump_file, "Function called in recursive cycle; ignoring\n"); return true; } - if (node->get_availability () <= AVAIL_INTERPOSABLE) + /* Save some work and do not analyze functions which are interposable and + do not have any non-interposable aliases. */ + if (node->get_availability () <= AVAIL_INTERPOSABLE + && !node->has_aliases_p ()) { if (dump_file) fprintf (dump_file, - "Function is not available or interposable; not analyzing.\n"); + "Function is interposable; not analyzing.\n"); return true; } return false; @@ -1806,11 +1812,6 @@ pass_local_pure_const::execute (function *fun) if (!TREE_READONLY (current_function_decl)) { warn_function_const (current_function_decl, !l->looping); - if (!skip) - { - node->set_const_flag (true, l->looping); - changed = true; - } if (dump_file) fprintf (dump_file, "Function found to be %sconst: %s\n", l->looping ? "looping " : "", @@ -1819,25 +1820,23 @@ pass_local_pure_const::execute (function *fun) else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) && !l->looping) { - if (!skip) - { - node->set_const_flag (true, false); - changed = true; - } if (dump_file) fprintf (dump_file, "Function found to be non-looping: %s\n", current_function_name ()); } + if (!skip && node->set_const_flag (true, l->looping)) + { + if (dump_file) + fprintf (dump_file, "Declaration updated to be %sconst: %s\n", + l->looping ? "looping " : "", + current_function_name ()); + changed = true; + } break; case IPA_PURE: if (!DECL_PURE_P (current_function_decl)) { - if (!skip) - { - node->set_pure_flag (true, l->looping); - changed = true; - } warn_function_pure (current_function_decl, !l->looping); if (dump_file) fprintf (dump_file, "Function found to be %spure: %s\n", @@ -1847,15 +1846,18 @@ pass_local_pure_const::execute (function *fun) else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) && !l->looping) { - if (!skip) - { - node->set_pure_flag (true, false); - changed = true; - } if (dump_file) fprintf (dump_file, "Function found to be non-looping: %s\n", current_function_name ()); } + if (!skip && node->set_pure_flag (true, l->looping)) + { + if (dump_file) + fprintf (dump_file, "Declaration updated to be %spure: %s\n", + l->looping ? "looping " : "", + current_function_name ()); + changed = true; + } break; default: |