> On Sun, May 25, 2014 at 6:54 AM, Jan Hubicka <hubi...@ucw.cz> wrote: > > Hi, > > this patch adds code to rerite references in vtable initializers to local > > aliases > > when doing so is a win. > > > > Bootstrapped/regtested x86_64-linux, comitted. > > This is the most likely patch to have caused build failures on > arm-linux-gnueabihf > ^ > /work/trunk-nightlies/builds/build-210913/armv7l-unknown-linux-gnueabihf/libstdc++-v3/include/backward/strstream:143:9: > note: _std::ostrstream::_ZTVSt10ostrstream_ was declared here > /work/trunk-nightlies/builds/build-210913/armv7l-unknown-linux-gnueabihf/libstdc++-v3/include/backward/strstream:160:9: > error: std::strstream::_ZTVSt9strstream.localalias.2 causes a section > type conflict with std::strstream::_ZTVSt9strstream > class strstream : public basic_iostream<char> > ^ > /work/trunk-nightlies/builds/build-210913/armv7l-unknown-linux-gnueabihf/libstdc++-v3/include/backward/strstream:160:9: > note: _std::strstream::_ZTVSt9strstream_ was declared here
I suppose it is because wrong readonly flag on the alias created. Does the following patch help? Index: symtab.c =================================================================== --- symtab.c (revision 210914) +++ symtab.c (working copy) @@ -1163,7 +1163,10 @@ (new_decl, node->decl); } else - new_node = varpool_create_variable_alias (new_decl, node->decl); + { + DECL_READONLY (new_decl) = DECL_READONLY (node->decl); + new_node = varpool_create_variable_alias (new_decl, node->decl); + } symtab_resolve_alias (new_node, node); gcc_assert (decl_binds_to_current_def_p (new_decl)); return new_node; > > > regards > Ramana > > > > > > Honza > > > > * ipa-visibility.c (can_replace_by_local_alias_in_vtable): New > > function. > > (update_vtable_references): New function. > > (function_and_variable_visibility): Rewrite also vtable > > initializers. > > * varpool.c (cgraph_variable_initializer_availability): Remove > > assert. > > Index: varpool.c > > =================================================================== > > --- varpool.c (revision 210908) > > +++ varpool.c (working copy) > > @@ -355,7 +355,6 @@ varpool_add_new_variable (tree decl) > > enum availability > > cgraph_variable_initializer_availability (varpool_node *node) > > { > > - gcc_assert (cgraph_function_flags_ready); > > if (!node->definition) > > return AVAIL_NOT_AVAILABLE; > > if (!TREE_PUBLIC (node->decl)) > > Index: ipa-visibility.c > > =================================================================== > > --- ipa-visibility.c (revision 210908) > > +++ ipa-visibility.c (working copy) > > @@ -343,6 +343,36 @@ can_replace_by_local_alias (symtab_node > > && !symtab_can_be_discarded (node)); > > } > > > > +/* Return true if we can replace refernece to NODE by local alias > > + within a virtual table. Generally we can replace function pointers > > + and virtual table pointers. */ > > + > > +bool > > +can_replace_by_local_alias_in_vtable (symtab_node *node) > > +{ > > + if (is_a <varpool_node *> (node) > > + && !DECL_VIRTUAL_P (node->decl)) > > + return false; > > + return can_replace_by_local_alias (node); > > +} > > + > > +/* walk_tree callback that rewrites initializer references. */ > > + > > +static tree > > +update_vtable_references (tree *tp, int *walk_subtrees, void *data > > ATTRIBUTE_UNUSED) > > +{ > > + if (TREE_CODE (*tp) == VAR_DECL > > + || TREE_CODE (*tp) == FUNCTION_DECL) > > + { > > + if (can_replace_by_local_alias_in_vtable (symtab_get_node (*tp))) > > + *tp = symtab_nonoverwritable_alias (symtab_get_node (*tp))->decl; > > + *walk_subtrees = 0; > > + } > > + else if (IS_TYPE_OR_DECL_P (*tp)) > > + *walk_subtrees = 0; > > + return NULL; > > +} > > + > > /* In LTO we can remove COMDAT groups and weak symbols. > > Either turn them into normal symbols or external symbol depending on > > resolution info. */ > > @@ -625,6 +655,34 @@ function_and_variable_visibility (bool w > > vnode->resolution = LDPR_PREVAILING_DEF_IRONLY; > > } > > update_visibility_by_resolution_info (vnode); > > + > > + /* Update virutal tables to point to local aliases where possible. > > */ > > + if (DECL_VIRTUAL_P (vnode->decl) > > + && !DECL_EXTERNAL (vnode->decl)) > > + { > > + int i; > > + struct ipa_ref *ref; > > + bool found = false; > > + > > + /* See if there is something to update. */ > > + for (i = 0; ipa_ref_list_referring_iterate (&vnode->ref_list, > > + i, ref); i++) > > + if (ref->use == IPA_REF_ADDR > > + && can_replace_by_local_alias_in_vtable (ref->referred)) > > + { > > + found = true; > > + break; > > + } > > + if (found) > > + { > > + struct pointer_set_t *visited_nodes = pointer_set_create (); > > + walk_tree (&DECL_INITIAL (vnode->decl), > > + update_vtable_references, NULL, visited_nodes); > > + pointer_set_destroy (visited_nodes); > > + ipa_remove_all_references (&vnode->ref_list); > > + record_references_in_initializer (vnode->decl, false); > > + } > > + } > > } > > > > if (dump_file)