Hi, symbol summaries are not PCH safe and thus thunk_info summary can not be created before parsing is finished. This patch stores thunk infos into a vector before they are attachd to actual symbol nodes at symtab construction time.
I am not sure how to add the testcase - I did not find similar one in pch subdirectory... Bootstrapped/regtested x86_64-linux, will commit it tomrrow. gcc/ChangeLog: 2020-10-29 Jan Hubicka <hubi...@ucw.cz> PR pch/97593 * cgraph.c (cgraph_node::create_thunk): Register thunk as early during parsing. * cgraphunit.c (analyze_functions): Call thunk_info::process_early_thunks. * symtab-thunks.cc (struct unprocessed_thunk): New struct. (thunks): New static variable. (thunk_info::register_early): New member function. (thunk_info::process_early_thunks): New member function. * symtab-thunks.h (thunk_info::register_early): Declare. (thunk_info::process_early_thunks): Declare. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index d1a773d386f..9129bcf12d2 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -633,13 +633,20 @@ cgraph_node::create_thunk (tree alias, tree, bool this_adjusting, node->thunk = true; node->definition = true; - thunk_info *i = thunk_info::get_create (node); + thunk_info *i; + thunk_info local_info; + if (symtab->state < CONSTRUCTION) + i = &local_info; + else + i = thunk_info::get_create (node); i->fixed_offset = fixed_offset; i->virtual_value = virtual_value; i->indirect_offset = indirect_offset; i->alias = real_alias; i->this_adjusting = this_adjusting; i->virtual_offset_p = virtual_offset != NULL; + if (symtab->state < CONSTRUCTION) + i->register_early (node); return node; } diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 08b93cb00ee..3a9895825b1 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1155,6 +1155,8 @@ analyze_functions (bool first_time) symtab->state = CONSTRUCTION; input_location = UNKNOWN_LOCATION; + thunk_info::process_early_thunks (); + /* Ugly, but the fixup cannot happen at a time same body alias is created; C++ FE is confused about the COMDAT groups being right. */ if (symtab->cpp_implicit_aliases_done) diff --git a/gcc/symtab-thunks.cc b/gcc/symtab-thunks.cc index 1a4aaa2d80b..b11fd4a2cc2 100644 --- a/gcc/symtab-thunks.cc +++ b/gcc/symtab-thunks.cc @@ -52,6 +52,14 @@ along with GCC; see the file COPYING3. If not see /* Used for vtable lookup in thunk adjusting. */ static GTY (()) tree vtable_entry_type; +struct GTY (()) unprocessed_thunk +{ + cgraph_node *node; + thunk_info *info; +}; +/* To be PCH safe we store thunks into a vector before end of compilation + unit. */ +static vec <unprocessed_thunk, va_gc> GTY (()) *thunks; namespace { @@ -147,6 +155,33 @@ thunk_info::hash () return hstate.end (); } +/* Add unprocessed thunk. */ +void +thunk_info::register_early (cgraph_node *node) +{ + unprocessed_thunk entry = {node, new (ggc_alloc <thunk_info> ()) thunk_info}; + *entry.info = *this; + vec_safe_push (thunks, entry); +} + +/* Attach recorded thunks to cgraph_nodes. + All this is done only to avoid need to stream summaries to PCH. */ +void +thunk_info::process_early_thunks () +{ + unprocessed_thunk *e; + unsigned int i; + if (!thunks) + return; + + FOR_EACH_VEC_ELT (*thunks, i, e) + { + *thunk_info::get_create (e->node) = *e->info; + } + vec_free (thunks); + thunks = NULL; +} + /* Adjust PTR by the constant FIXED_OFFSET, by the vtable offset indicated by VIRTUAL_OFFSET, and by the indirect offset indicated by INDIRECT_OFFSET, if it is non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and zero diff --git a/gcc/symtab-thunks.h b/gcc/symtab-thunks.h index a23fc552950..41a684995b3 100644 --- a/gcc/symtab-thunks.h +++ b/gcc/symtab-thunks.h @@ -77,6 +77,7 @@ struct GTY(()) thunk_info { fixed_offset = other.fixed_offset; virtual_value = other.virtual_value; indirect_offset = other.indirect_offset; + alias = other.alias; this_adjusting = other.this_adjusting; virtual_offset_p = other.virtual_offset_p; return *this; @@ -133,6 +134,12 @@ struct GTY(()) thunk_info { /* Remove thunk_info. */ static void remove (cgraph_node *node); + /* Add unprocessed thunk. */ + void register_early (cgraph_node *node); + + /* Attach recorded thunks to cgraph_nodes. */ + static void process_early_thunks (); + /* Release all thunk_infos. */ static void release (void); };