aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-12-03 05:19:44 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2015-12-03 04:19:44 +0000
commit9644e52a6b3ebdcfd1158532f82843d55ec6365d (patch)
tree7ab83a95dc3db367845e5c16d2962f95c5cd9fe4 /gcc
parent89bbe9ba36dfcf71ab9e5d85c447f3511e7f8d97 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/ipa-pure-const.c58
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;