aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2021-11-11 14:35:10 +0100
committerJan Hubicka <jh@suse.cz>2021-11-11 14:35:10 +0100
commit61396dfb2acfe956d420b279b2becec1c4f81ba2 (patch)
tree57f81e90ccd47b546d3d5f4715511814beae1cc5 /gcc
parente106221db2eee30641b856db68858f1131c0fcf5 (diff)
downloadgcc-61396dfb2acfe956d420b279b2becec1c4f81ba2.zip
gcc-61396dfb2acfe956d420b279b2becec1c4f81ba2.tar.gz
gcc-61396dfb2acfe956d420b279b2becec1c4f81ba2.tar.bz2
Fix noreturn discovery.
Fix ipa-pure-const handling of noreturn flags. It is not safe to set it for interposable symbols and we should also set it for aliases (just like we do for other flags). This patch merely copies other flag handling and implements it here. gcc/ChangeLog: 2021-11-11 Jan Hubicka <hubicka@ucw.cz> * cgraph.c (set_noreturn_flag_1): New function. (cgraph_node::set_noreturn_flag): New member function * cgraph.h (cgraph_node::set_noreturn_flags): Declare. * ipa-pure-const.c (pass_local_pure_const::execute): Use it.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cgraph.c47
-rw-r--r--gcc/cgraph.h4
-rw-r--r--gcc/ipa-pure-const.c5
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)