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> 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 PR ipa/68184
* cgraphunit.c (cgraph_node::analyze): Set can_throw_external. * cgraphunit.c (cgraph_node::analyze): Set can_throw_external.
...@@ -1124,11 +1124,18 @@ pure_const_read_summary (void) ...@@ -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 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. /* Return true if NODE is self recursive function.
...@@ -1491,7 +1498,8 @@ propagate_nothrow (void) ...@@ -1491,7 +1498,8 @@ propagate_nothrow (void)
int i; int i;
struct ipa_dfs_info * w_info; 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) if (dump_file)
{ {
cgraph_node::dump_cgraph (dump_file); cgraph_node::dump_cgraph (dump_file);
...@@ -1515,32 +1523,38 @@ propagate_nothrow (void) ...@@ -1515,32 +1523,38 @@ propagate_nothrow (void)
while (w && !can_throw) while (w && !can_throw)
{ {
struct cgraph_edge *e, *ie; 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; funct_state w_l = get_function_state (w);
struct cgraph_node *y = e->callee->
function_or_virtual_thunk_symbol (&avail);
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) /* We can use info about the callee only if we know it can
&& e->can_throw_external) not be interposed. */
if (avail <= AVAIL_INTERPOSABLE
|| (!TREE_NOTHROW (y->decl)
&& get_function_state (y)->can_throw))
can_throw = true; can_throw = true;
} }
else if (e->can_throw_external && !TREE_NOTHROW (y->decl)) for (ie = w->indirect_calls; ie && !can_throw;
can_throw = true; 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_info = (struct ipa_dfs_info *) w->aux;
w = w_info->next_cycle; w = w_info->next_cycle;
} }
...@@ -1650,7 +1664,7 @@ skip_function_for_local_pure_const (struct cgraph_node *node) ...@@ -1650,7 +1664,7 @@ skip_function_for_local_pure_const (struct cgraph_node *node)
if (node->get_availability () <= AVAIL_INTERPOSABLE) if (node->get_availability () <= AVAIL_INTERPOSABLE)
{ {
if (dump_file) 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 true;
} }
return false; 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