diff options
| -rw-r--r-- | gcc/cgraph.c | 47 | ||||
| -rw-r--r-- | gcc/cgraph.h | 4 | ||||
| -rw-r--r-- | gcc/ipa-pure-const.c | 5 |
3 files changed, 53 insertions, 3 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c index c67d300..466b66d 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2614,6 +2614,53 @@ cgraph_node::set_malloc_flag (bool malloc_p) return changed; } +/* Worker to set noreturng flag. */ +static void +set_noreturn_flag_1 (cgraph_node *node, bool noreturn_p, bool *changed) +{ + if (noreturn_p && !TREE_THIS_VOLATILE (node->decl)) + { + TREE_THIS_VOLATILE (node->decl) = true; + *changed = true; + } + + ipa_ref *ref; + FOR_EACH_ALIAS (node, ref) + { + cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring); + if (!noreturn_p || alias->get_availability () > AVAIL_INTERPOSABLE) + set_noreturn_flag_1 (alias, noreturn_p, changed); + } + + for (cgraph_edge *e = node->callers; e; e = e->next_caller) + if (e->caller->thunk + && (!noreturn_p || e->caller->get_availability () > AVAIL_INTERPOSABLE)) + set_noreturn_flag_1 (e->caller, noreturn_p, changed); +} + +/* Set TREE_THIS_VOLATILE on NODE's decl and on NODE's aliases if any. */ + +bool +cgraph_node::set_noreturn_flag (bool noreturn_p) +{ + bool changed = false; + + if (!noreturn_p || get_availability () > AVAIL_INTERPOSABLE) + set_noreturn_flag_1 (this, noreturn_p, &changed); + else + { + ipa_ref *ref; + + FOR_EACH_ALIAS (this, ref) + { + cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring); + if (!noreturn_p || alias->get_availability () > AVAIL_INTERPOSABLE) + set_noreturn_flag_1 (alias, noreturn_p, &changed); + } + } + return changed; +} + /* Worker to set_const_flag. */ static void diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 0a1f7c8..e42e305 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1167,6 +1167,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node if any. */ bool set_malloc_flag (bool malloc_p); + /* SET TREE_THIS_VOLATILE on cgraph_node's decl and on aliases of the node + if any. */ + bool set_noreturn_flag (bool noreturn_p); + /* If SET_CONST is true, mark function, aliases and thunks to be ECF_CONST. If SET_CONST if false, clear the flag. diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 505ed4f..84a028b 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -2132,11 +2132,10 @@ pass_local_pure_const::execute (function *fun) current_function_name ()); /* Update declaration and reduce profile to executed once. */ - TREE_THIS_VOLATILE (current_function_decl) = 1; + if (cgraph_node::get (current_function_decl)->set_noreturn_flag (true)) + changed = true; if (node->frequency > NODE_FREQUENCY_EXECUTED_ONCE) node->frequency = NODE_FREQUENCY_EXECUTED_ONCE; - - changed = true; } switch (l->pure_const_state) |
