diff mbox

Fix gcc.dg/lto/pr56297 failure

Message ID 20130902203641.GA20650@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Sept. 2, 2013, 8:36 p.m. UTC
Hi,
this patch fixes gcc.dg/lto/pr56297 failure.  Here we have two modules defining
global variable assigned to hard registers.  Those variables do not go into
assembler name hash because they have no real assembler name and consequentely
they are not merged.
We however may end up with two declarations being merged by tree merging and
then symtab needs to compensate.  We solve precisely same problem for
builtins and abstract functions already. This patch thus makes us to do the
right thing for variables, too.

I also added comment since the code is bit weird.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

Honza

	* lto-symtab.c (lto_symtab_merge_symbols): Add comments; merge
	duplicated nodes for assembler names.
	* symtab.c (symtab_unregister_node): Do not attempt to unlink
	hard registers from assembler name hash.
diff mbox

Patch

Index: lto-symtab.c
===================================================================
--- lto-symtab.c	(revision 202182)
+++ lto-symtab.c	(working copy)
@@ -586,6 +586,9 @@  lto_symtab_merge_symbols (void)
       FOR_EACH_SYMBOL (node)
 	{
 	  cgraph_node *cnode, *cnode2;
+	  varpool_node *vnode;
+	  symtab_node node2;
+
 	  if (!node->symbol.analyzed && node->symbol.alias_target)
 	    {
 	      symtab_node tgt = symtab_node_for_asm (node->symbol.alias_target);
@@ -594,22 +597,37 @@  lto_symtab_merge_symbols (void)
 		symtab_resolve_alias (node, tgt);
 	    }
 	  node->symbol.aux = NULL;
-	  
+
 	  if (!(cnode = dyn_cast <cgraph_node> (node))
 	      || !cnode->clone_of
 	      || cnode->clone_of->symbol.decl != cnode->symbol.decl)
 	    {
+	      /* Builtins are not merged via decl merging.  It is however
+		 possible that tree merging unified the declaration.  We
+		 do not want duplicate entries in symbol table.  */
 	      if (cnode && DECL_BUILT_IN (node->symbol.decl)
 		  && (cnode2 = cgraph_get_node (node->symbol.decl))
 		  && cnode2 != cnode)
 		lto_cgraph_replace_node (cnode2, cnode);
 
+	      /* The user defined assembler variables are also not unified by their
+		 symbol name (since it is irrelevant), but we need to unify symbol
+		 nodes if tree merging occured.  */
+	      if ((vnode = dyn_cast <varpool_node> (node))
+		  && DECL_HARD_REGISTER (vnode->symbol.decl)
+		  && (node2 = symtab_get_node (vnode->symbol.decl))
+		  && node2 != node)
+		lto_varpool_replace_node (dyn_cast <varpool_node> (node2),
+					  vnode);
+	  
+
 	      /* Abstract functions may have duplicated cgraph nodes attached;
 		 remove them.  */
 	      else if (cnode && DECL_ABSTRACT (cnode->symbol.decl)
 		       && (cnode2 = cgraph_get_node (node->symbol.decl))
 		       && cnode2 != cnode)
 		cgraph_remove_node (cnode2);
+
 	      symtab_insert_node_to_hashtable ((symtab_node)node);
 	    }
 	}
Index: symtab.c
===================================================================
--- symtab.c	(revision 202182)
+++ symtab.c	(working copy)
@@ -283,7 +283,8 @@  symtab_unregister_node (symtab_node node
       else
 	*slot = replacement_node;
     }
-  unlink_from_assembler_name_hash (node, false);
+  if (!is_a <varpool_node> (node) || !DECL_HARD_REGISTER (node->symbol.decl))
+    unlink_from_assembler_name_hash (node, false);
 }
 
 /* Return symbol table node associated with DECL, if any,