diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2015-12-03 05:19:44 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2015-12-03 04:19:44 +0000 |
commit | 9644e52a6b3ebdcfd1158532f82843d55ec6365d (patch) | |
tree | 7ab83a95dc3db367845e5c16d2962f95c5cd9fe4 | |
parent | 89bbe9ba36dfcf71ab9e5d85c447f3511e7f8d97 (diff) | |
download | gcc-9644e52a6b3ebdcfd1158532f82843d55ec6365d.zip gcc-9644e52a6b3ebdcfd1158532f82843d55ec6365d.tar.gz gcc-9644e52a6b3ebdcfd1158532f82843d55ec6365d.tar.bz2 |
ipa-pure-const.c (ignore_edge): Rename to ...
* ipa-pure-const.c (ignore_edge): Rename to ...
(ignore_edge_for_nothrow) ... this one; also ignore eges to
interposable functions or ones that can not throw.
(propagate_nothrow): Fix handling of availability.
From-SVN: r231218
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ipa-pure-const.c | 58 |
2 files changed, 43 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d96d7b..0cb5593 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2015-12-02 Jan Hubicka <hubicka@ucw.cz> + * ipa-pure-const.c (ignore_edge): Rename to ... + (ignore_edge_for_nothrow) ... this one; also ignore eges to + interposable functions or ones that can not throw. + (propagate_nothrow): Fix handling of availability. + +2015-12-02 Jan Hubicka <hubicka@ucw.cz> + PR ipa/68184 * cgraphunit.c (cgraph_node::analyze): Set can_throw_external. diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 840ca7a..654791a 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -1124,11 +1124,18 @@ pure_const_read_summary (void) } } +/* We only propagate across edges that can throw externally and their callee + is not interposable. */ static bool -ignore_edge (struct cgraph_edge *e) +ignore_edge_for_nothrow (struct cgraph_edge *e) { - return (!e->can_throw_external); + if (!e->can_throw_external || TREE_NOTHROW (e->callee->decl)) + return true; + + enum availability avail; + cgraph_node *n = e->callee->function_or_virtual_thunk_symbol (&avail); + return (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (n->decl)); } /* Return true if NODE is self recursive function. @@ -1491,7 +1498,8 @@ propagate_nothrow (void) int i; struct ipa_dfs_info * w_info; - order_pos = ipa_reduced_postorder (order, true, false, ignore_edge); + order_pos = ipa_reduced_postorder (order, true, false, + ignore_edge_for_nothrow); if (dump_file) { cgraph_node::dump_cgraph (dump_file); @@ -1515,32 +1523,38 @@ propagate_nothrow (void) while (w && !can_throw) { struct cgraph_edge *e, *ie; - funct_state w_l = get_function_state (w); - - if (w_l->can_throw - || w->get_availability () == AVAIL_INTERPOSABLE) - can_throw = true; - for (e = w->callees; e && !can_throw; e = e->next_callee) + if (!TREE_NOTHROW (w->decl)) { - enum availability avail; - struct cgraph_node *y = e->callee-> - function_or_virtual_thunk_symbol (&avail); + funct_state w_l = get_function_state (w); - if (avail > AVAIL_INTERPOSABLE) + if (w_l->can_throw + || w->get_availability () == AVAIL_INTERPOSABLE) + can_throw = true; + + for (e = w->callees; e && !can_throw; e = e->next_callee) { - funct_state y_l = get_function_state (y); + enum availability avail; + + if (!e->can_throw_external || TREE_NOTHROW (e->callee->decl)) + continue; + + struct cgraph_node *y = e->callee-> + function_or_virtual_thunk_symbol (&avail); - if (y_l->can_throw && !TREE_NOTHROW (w->decl) - && e->can_throw_external) + /* We can use info about the callee only if we know it can + not be interposed. */ + if (avail <= AVAIL_INTERPOSABLE + || (!TREE_NOTHROW (y->decl) + && get_function_state (y)->can_throw)) can_throw = true; } - else if (e->can_throw_external && !TREE_NOTHROW (y->decl)) - can_throw = true; + for (ie = w->indirect_calls; ie && !can_throw; + ie = ie->next_callee) + if (ie->can_throw_external + && !(ie->indirect_info->ecf_flags & ECF_NOTHROW)) + can_throw = true; } - for (ie = w->indirect_calls; ie && !can_throw; ie = ie->next_callee) - if (ie->can_throw_external) - can_throw = true; w_info = (struct ipa_dfs_info *) w->aux; w = w_info->next_cycle; } @@ -1650,7 +1664,7 @@ skip_function_for_local_pure_const (struct cgraph_node *node) if (node->get_availability () <= AVAIL_INTERPOSABLE) { if (dump_file) - fprintf (dump_file, "Function is not available or overwritable; not analyzing.\n"); + fprintf (dump_file, "Function is not available or interposable; not analyzing.\n"); return true; } return false; |