cgraph: Move next/previous from symtab to toplevel_node [PR122955]

Currently the GC marker functions don't support chain_next on non-toplevel
tag structures (and does not error out either). So since r16-4747-g529c25ed6e0a06
if there are a lot of chained symtab_nodes (happens most likely with LTO), the GC
marker function could cause a stack overflow because of the recusive nature of the marker.

This fixes the problem by moving next/previous to toplevel_node. I had originally
thought about doing chain_next/chain_prev and using is_a<symtab_node *> to get if
it was symtab_node and then used the next/previous from there. But it was noticed that
asm_node had a next too (though not using chain_next) so adding a previous is not going
to much more space anyways; there will not be many toplevel inline-asm anyways.

Bootstraped and tested on x86_64-linux-gnu.

	PR ipa/122955
gcc/ChangeLog:

	* cgraph.h (toplevel_node): Add next and previous fields.
	Add chain_next and chain_prev to GTY.
	(symtab_node): Remove next and previous field. Remove chain_next and chain_prev
	from the GTY.
	(asm_node): Remove next field.
	(symtab_node::next_defined_symbol): Use save_as_a<symtab_node*> around next.
	(symbol_table::unregister): Likewise
	(FOR_EACH_SYMBOL): Likewise
	(symbol_table::first_defined_symbol): Likewise
	(symbol_table::first_variable): Likewise
	(symbol_table::next_variable): Likewise
	(symbol_table::first_static_initializer): Likewise
	(symbol_table::next_static_initializer): Likewise
	(symbol_table::first_defined_variable): Likewise
	(symbol_table::next_defined_variable): Likewise
	(symbol_table::first_defined_function): Likewise
	(symbol_table::next_defined_function): Likewise
	(symbol_table::first_function): Likewise
	(symbol_table::next_function): Likewise
	(symbol_table::first_function_with_gimple_body): Likewise
	(symbol_table::next_function_with_gimple_body): Likewise
	* cgraphunit.cc (analyze_functions): Likewise
	(output_in_order): Likewise
	* lto-streamer-out.cc (lto_output): Use save_as_a<asm_node*> around next.
	* symtab.cc (symtab_node::verify_symtab_nodes): Likewise.

gcc/lto/ChangeLog:

	* lto-partition.cc (lto_1_to_1_map): Use save_as_a<asm_node*> around next.
	(create_asm_partition): Likewise.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
This commit is contained in:
Andrew Pinski
2025-12-03 13:46:43 -08:00
parent bcbb536551
commit e9c12ffd71
5 changed files with 48 additions and 42 deletions

View File

@@ -107,7 +107,9 @@ enum symbol_partitioning_class
/* Base of all toplevel entries.
Inherited by symtab_node and asm_node. */
struct GTY ((desc ("%h.type"), tag ("TOPLEVEL_BASE"))) toplevel_node {
struct GTY ((desc ("%h.type"), tag ("TOPLEVEL_BASE"),
chain_next("%h.next"),
chain_prev("%h.previous"))) toplevel_node {
/* Constructor. */
explicit toplevel_node (toplevel_type t)
: lto_file_data (NULL), order (-1), type (t)
@@ -116,6 +118,10 @@ struct GTY ((desc ("%h.type"), tag ("TOPLEVEL_BASE"))) toplevel_node {
/* File stream where this node is being written to. */
struct lto_file_decl_data * lto_file_data;
/* Linked list of toplevel entries. */
toplevel_node *next = nullptr;
toplevel_node *previous = nullptr;
/* Ordering of all cgraph nodes. */
int order;
@@ -125,8 +131,7 @@ struct GTY ((desc ("%h.type"), tag ("TOPLEVEL_BASE"))) toplevel_node {
/* Base of all entries in the symbol table.
The symtab_node is inherited by cgraph and varpol nodes. */
struct GTY ((tag ("SYMTAB_SYMBOL"),
chain_next ("%h.next"), chain_prev ("%h.previous")))
struct GTY ((tag ("SYMTAB_SYMBOL")))
symtab_node: public toplevel_node
{
public:
@@ -633,10 +638,6 @@ public:
/* Declaration representing the symbol. */
tree decl;
/* Linked list of symbol table entries starting with symtab_nodes. */
symtab_node *next;
symtab_node *previous;
/* Linked list of symbols with the same asm name. There may be multiple
entries for single symbol name during LTO, because symbols are renamed
only after partitioning.
@@ -2243,10 +2244,8 @@ private:
struct GTY ((tag ("TOPLEVEL_ASM"))) asm_node: public toplevel_node {
explicit asm_node (tree asm_str)
: toplevel_node (TOPLEVEL_ASM), next (NULL), asm_str (asm_str)
: toplevel_node (TOPLEVEL_ASM), asm_str (asm_str)
{}
/* Next asm node. */
asm_node *next;
/* String for this asm node. */
tree asm_str;
};
@@ -2867,9 +2866,9 @@ symtab_node::get_alias_target_tree ()
inline symtab_node *
symtab_node::next_defined_symbol (void)
{
symtab_node *node1 = next;
symtab_node *node1 = safe_as_a<symtab_node *>(next);
for (; node1; node1 = node1->next)
for (; node1; node1 = safe_as_a<symtab_node *>(node1->next))
if (node1->definition)
return node1;
@@ -2997,7 +2996,7 @@ symbol_table::unregister (symtab_node *node)
if (node->previous)
node->previous->next = node->next;
else
nodes = node->next;
nodes = safe_as_a<symtab_node *>(node->next);
if (node->next)
node->next->previous = node->previous;
@@ -3026,7 +3025,8 @@ symbol_table::first_symbol (void)
/* Walk all symbols. */
#define FOR_EACH_SYMBOL(node) \
for ((node) = symtab->first_symbol (); (node); (node) = (node)->next)
for ((node) = symtab->first_symbol (); (node); \
(node) = safe_as_a<symtab_node *>((node)->next))
/* Return first static symbol with definition. */
inline symtab_node *
@@ -3034,7 +3034,8 @@ symbol_table::first_defined_symbol (void)
{
symtab_node *node;
for (node = nodes; node; node = node->next)
for (node = nodes; node;
node = safe_as_a<symtab_node *>(node->next))
if (node->definition)
return node;
@@ -3051,7 +3052,7 @@ inline varpool_node *
symbol_table::first_variable (void)
{
symtab_node *node;
for (node = nodes; node; node = node->next)
for (node = nodes; node; node = safe_as_a<symtab_node *>(node->next))
if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
return vnode;
return NULL;
@@ -3061,8 +3062,8 @@ symbol_table::first_variable (void)
inline varpool_node *
symbol_table::next_variable (varpool_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
symtab_node *node1 = safe_as_a<symtab_node *>(node->next);
for (; node1; node1 = safe_as_a<symtab_node *>(node1->next))
if (varpool_node *vnode1 = dyn_cast <varpool_node *> (node1))
return vnode1;
return NULL;
@@ -3078,7 +3079,7 @@ inline varpool_node *
symbol_table::first_static_initializer (void)
{
symtab_node *node;
for (node = nodes; node; node = node->next)
for (node = nodes; node; node = safe_as_a<symtab_node *>(node->next))
{
varpool_node *vnode = dyn_cast <varpool_node *> (node);
if (vnode && DECL_INITIAL (node->decl))
@@ -3091,8 +3092,8 @@ symbol_table::first_static_initializer (void)
inline varpool_node *
symbol_table::next_static_initializer (varpool_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
symtab_node *node1 = safe_as_a<symtab_node *>(node->next);
for (; node1; node1 = safe_as_a<symtab_node *>(node1->next))
{
varpool_node *vnode1 = dyn_cast <varpool_node *> (node1);
if (vnode1 && DECL_INITIAL (node1->decl))
@@ -3111,7 +3112,7 @@ inline varpool_node *
symbol_table::first_defined_variable (void)
{
symtab_node *node;
for (node = nodes; node; node = node->next)
for (node = nodes; node; node = safe_as_a<symtab_node *>(node->next))
{
varpool_node *vnode = dyn_cast <varpool_node *> (node);
if (vnode && vnode->definition)
@@ -3124,8 +3125,8 @@ symbol_table::first_defined_variable (void)
inline varpool_node *
symbol_table::next_defined_variable (varpool_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
symtab_node *node1 = safe_as_a<symtab_node *>(node->next);
for (; node1; node1 = safe_as_a<symtab_node *>(node1->next))
{
varpool_node *vnode1 = dyn_cast <varpool_node *> (node1);
if (vnode1 && vnode1->definition)
@@ -3143,7 +3144,7 @@ inline cgraph_node *
symbol_table::first_defined_function (void)
{
symtab_node *node;
for (node = nodes; node; node = node->next)
for (node = nodes; node; node = safe_as_a<symtab_node *>(node->next))
{
cgraph_node *cn = dyn_cast <cgraph_node *> (node);
if (cn && cn->definition)
@@ -3156,8 +3157,8 @@ symbol_table::first_defined_function (void)
inline cgraph_node *
symbol_table::next_defined_function (cgraph_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
symtab_node *node1 = safe_as_a<symtab_node *>(node->next);
for (; node1; node1 = safe_as_a<symtab_node *>(node1->next))
{
cgraph_node *cn1 = dyn_cast <cgraph_node *> (node1);
if (cn1 && cn1->definition)
@@ -3176,7 +3177,7 @@ inline cgraph_node *
symbol_table::first_function (void)
{
symtab_node *node;
for (node = nodes; node; node = node->next)
for (node = nodes; node; node = safe_as_a<symtab_node *>(node->next))
if (cgraph_node *cn = dyn_cast <cgraph_node *> (node))
return cn;
return NULL;
@@ -3186,8 +3187,8 @@ symbol_table::first_function (void)
inline cgraph_node *
symbol_table::next_function (cgraph_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
symtab_node *node1 = safe_as_a<symtab_node *>(node->next);
for (; node1; node1 = safe_as_a<symtab_node *>(node1->next))
if (cgraph_node *cn1 = dyn_cast <cgraph_node *> (node1))
return cn1;
return NULL;
@@ -3198,7 +3199,7 @@ inline cgraph_node *
symbol_table::first_function_with_gimple_body (void)
{
symtab_node *node;
for (node = nodes; node; node = node->next)
for (node = nodes; node; node = safe_as_a<symtab_node *>(node->next))
{
cgraph_node *cn = dyn_cast <cgraph_node *> (node);
if (cn && cn->has_gimple_body_p ())
@@ -3211,8 +3212,8 @@ symbol_table::first_function_with_gimple_body (void)
inline cgraph_node *
symbol_table::next_function_with_gimple_body (cgraph_node *node)
{
symtab_node *node1 = node->next;
for (; node1; node1 = node1->next)
symtab_node *node1 = safe_as_a<symtab_node *>(node->next);
for (; node1; node1 = safe_as_a<symtab_node *>(node1->next))
{
cgraph_node *cn1 = dyn_cast <cgraph_node *> (node1);
if (cn1 && cn1->has_gimple_body_p ())

View File

@@ -1210,8 +1210,8 @@ analyze_functions (bool first_time)
/* First identify the trivially needed symbols. */
for (node = symtab->first_symbol ();
node != first_analyzed
&& node != first_analyzed_var; node = node->next)
node != first_analyzed && node != first_analyzed_var;
node = safe_as_a<symtab_node *>(node->next))
{
/* Convert COMDAT group designators to IDENTIFIER_NODEs. */
node->get_comdat_group_id ();
@@ -1373,7 +1373,7 @@ analyze_functions (bool first_time)
node != first_handled
&& node != first_handled_var; node = next)
{
next = node->next;
next = safe_as_a<symtab_node *>(node->next);
/* For symbols declared locally we clear TREE_READONLY when emitting
the constructor (if one is needed). For external declarations we can
not safely assume that the type is readonly because we may be called
@@ -1428,7 +1428,7 @@ analyze_functions (bool first_time)
}
node->aux = NULL;
}
for (;node; node = node->next)
for (;node; node = safe_as_a<symtab_node *>(node->next))
node->aux = NULL;
first_analyzed = symtab->first_function ();
first_analyzed_var = symtab->first_variable ();
@@ -2203,7 +2203,8 @@ output_in_order (void)
&& !DECL_HAS_VALUE_EXPR_P (vnode->decl))
nodes.safe_push (cgraph_order_sort (vnode));
for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
for (anode = symtab->first_asm_symbol (); anode;
anode = safe_as_a<asm_node*>(anode->next))
nodes.safe_push (cgraph_order_sort (anode));
/* Sort nodes by order. */

View File

@@ -2828,7 +2828,9 @@ lto_output (void)
if (!flag_wpa)
{
asm_node *anode;
for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
for (anode = symtab->first_asm_symbol ();
anode;
anode = safe_as_a<asm_node*>(anode->next))
lto_set_symtab_encoder_in_partition (encoder, anode);
}

View File

@@ -383,7 +383,7 @@ lto_1_to_1_map (void)
}
struct asm_node *anode;
for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
for (anode = symtab->first_asm_symbol (); anode; anode = safe_as_a<asm_node*>(anode->next))
node_into_file_partition (anode, pmap);
create_partition_if_empty ();
@@ -406,7 +406,7 @@ create_asm_partition (void)
if (anode)
{
ltrans_partition partition = new_partition ("asm_nodes");
for (; anode; anode = anode->next)
for (; anode; anode = safe_as_a<asm_node*>(anode->next))
add_symbol_to_partition (partition, anode);
}
}

View File

@@ -1485,7 +1485,9 @@ symtab_node::verify_symtab_nodes (void)
hash_map<tree, symtab_node *> comdat_head_map (251);
asm_node *anode;
for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
for (anode = symtab->first_asm_symbol ();
anode;
anode = safe_as_a<asm_node*>(anode->next))
if (anode->order < 0 || anode->order >= symtab->order)
{
error ("invalid order in asm node %i", anode->order);