Commit 9644e52a by Jan Hubicka Committed by Jan Hubicka

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
parent 89bbe9ba
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.
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment