Commit Message
Hi,
this patch fixes 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.
Bootstrapped/regtested x86_64-linux, will commit it shortly.
Honza
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.
@@ -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
@@ -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.
@@ -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)