Fix resolution handling WRT incremental linking

Jan Hubicka hubicka@ucw.cz
Sun Nov 29 19:32:00 GMT 2015


Hi,
I went through the visibility code and update it for incremental linking.
On few places we now need to take into account the fact that next round
of static linking may remove whole sections, common symbols and comdats.
Also we can't assume that hidden symbols have unique name as we do not know
what extra hidden symbols will be introduced later.

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

Honza

	* cgraph.c (cgraph_node::make_local): No name is unique during
	incremental linking.
	* cgraph.h (can_be_discarded_p): Update comment; also common and
	WEAK in named sections can be discarded; when doing incremental
	link do not rely on resolution being the final one.
	* varasm.c (default_binds_local_p_3, decl_binds_to_current_def_p):
	When symbol can be discarded, do not rely on resolution info.
	* symtab.c (symtab_node::nonzero_address): Take into account that
	symbol can be discarded.
	* ipa-visibility.c (update_visibility_by_resolution_info): Handle
	definition correctly.
	(function_and_variable_visibility): Do not set unique_name when
	incrementally linking.
	
	
Index: varasm.c
===================================================================
--- varasm.c	(revision 231020)
+++ varasm.c	(working copy)
@@ -6837,7 +6837,9 @@ default_binds_local_p_3 (const_tree exp,
     {
       if (node->in_other_partition)
 	defined_locally = true;
-      if (resolution_to_local_definition_p (node->resolution))
+      if (flag_incremental_link && node->can_be_discarded_p ())
+	;
+      else if (resolution_to_local_definition_p (node->resolution))
 	defined_locally = resolved_locally = true;
       else if (resolution_local_p (node->resolution))
 	resolved_locally = true;
@@ -6930,7 +6932,8 @@ decl_binds_to_current_def_p (const_tree
   /* When resolution is available, just use it.  */
   if (symtab_node *node = symtab_node::get (decl))
     {
-      if (node->resolution != LDPR_UNKNOWN)
+      if (node->resolution != LDPR_UNKNOWN
+	  && (!flag_incremental_link || !node->can_be_discarded_p ()))
 	return resolution_to_local_definition_p (node->resolution);
     }
 
Index: symtab.c
===================================================================
--- symtab.c	(revision 231020)
+++ symtab.c	(working copy)
@@ -1713,6 +1713,7 @@ symtab_node::nonzero_address ()
 	      return true;
 	  if (target->resolution != LDPR_UNKNOWN
 	      && target->resolution != LDPR_UNDEF
+	      && !target->can_be_discarded_p ()
 	      && flag_delete_null_pointer_checks)
 	    return true;
 	  return false;
@@ -1751,6 +1752,7 @@ symtab_node::nonzero_address ()
   /* As the last resort, check the resolution info.  */
   if (resolution != LDPR_UNKNOWN
       && resolution != LDPR_UNDEF
+      && !can_be_discarded_p ()
       && flag_delete_null_pointer_checks)
     return true;
   return false;
Index: ipa-visibility.c
===================================================================
--- ipa-visibility.c	(revision 231020)
+++ ipa-visibility.c	(working copy)
@@ -413,10 +413,10 @@ update_visibility_by_resolution_info (sy
 	    DECL_WEAK (next->decl) = false;
 	    next->set_comdat_group (NULL);
 	  }
-	if (next->externally_visible
-	    && !define)
+	if (!define)
 	  {
-	    DECL_EXTERNAL (next->decl) = true;
+	    if (next->externally_visible)
+	      DECL_EXTERNAL (next->decl) = true;
 	    next->set_comdat_group (NULL);
 	  }
       }
@@ -513,10 +513,10 @@ function_and_variable_visibility (bool w
 	{
 	  gcc_assert (whole_program || in_lto_p
 		      || !TREE_PUBLIC (node->decl));
-	  node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
-				|| node->unique_name
-				|| node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
-				&& TREE_PUBLIC (node->decl));
+	  node->unique_name |= ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
+				 || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
+				&& TREE_PUBLIC (node->decl)
+				&& !flag_incremental_link);
 	  node->resolution = LDPR_PREVAILING_DEF_IRONLY;
 	  if (node->same_comdat_group && TREE_PUBLIC (node->decl))
 	    {
@@ -532,10 +532,10 @@ function_and_variable_visibility (bool w
 		  if (!next->alias)
 		    next->set_section (NULL);
 		  next->make_decl_local ();
-		  next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
-					|| next->unique_name
-					|| next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
-				       && TREE_PUBLIC (next->decl));
+		  next->unique_name |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
+					 || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
+				        && TREE_PUBLIC (next->decl)
+					&& !flag_incremental_link);
 		}
 	      /* cgraph_externally_visible_p has already checked all other nodes
 	         in the group and they will all be made local.  We need to
@@ -657,10 +657,11 @@ function_and_variable_visibility (bool w
 	  && !vnode->weakref)
 	{
 	  gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->decl));
-	  vnode->unique_name = ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY
-			         || vnode->resolution
+	  vnode->unique_name |= ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY
+			          || vnode->resolution
 				      == LDPR_PREVAILING_DEF_IRONLY_EXP)
-			        && TREE_PUBLIC (vnode->decl));
+			         && TREE_PUBLIC (vnode->decl)
+				 && !flag_incremental_link);
 	  if (vnode->same_comdat_group && TREE_PUBLIC (vnode->decl))
 	    {
 	      symtab_node *next = vnode;
@@ -675,10 +676,10 @@ function_and_variable_visibility (bool w
 		  if (!next->alias)
 		    next->set_section (NULL);
 		  next->make_decl_local ();
-		  next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
-					|| next->unique_name
-					|| next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
-				       && TREE_PUBLIC (next->decl));
+		  next->unique_name |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
+					 || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
+				        && TREE_PUBLIC (next->decl)
+					&& !flag_incremental_link);
 		}
 	      vnode->dissolve_same_comdat_group_list ();
 	    }
Index: cgraph.c
===================================================================
--- cgraph.c	(revision 231020)
+++ cgraph.c	(working copy)
@@ -2253,8 +2253,9 @@ cgraph_node::make_local (cgraph_node *no
       node->forced_by_abi = false;
       node->local.local = true;
       node->set_section (NULL);
-      node->unique_name = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
-				  || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
+      node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
+			   || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
+			   && !flag_incremental_link);
       node->resolution = LDPR_PREVAILING_DEF_IRONLY;
       gcc_assert (node->get_availability () == AVAIL_LOCAL);
     }
Index: cgraph.h
===================================================================
--- cgraph.h	(revision 231020)
+++ cgraph.h	(working copy)
@@ -319,15 +319,23 @@ public:
   /* Return true when there are references to the node.  */
   bool referred_to_p (bool include_self = true);
 
-  /* Return true if NODE can be discarded by linker from the binary.  */
+  /* Return true if symbol can be discarded by linker from the binary.
+     Assume that symbol is used (so there is no need to take into account
+     garbage collecting linkers)
+
+     This can happen for comdats, commons and weaks when they are previaled
+     by other definition at static linking time.  */
   inline bool
   can_be_discarded_p (void)
   {
     return (DECL_EXTERNAL (decl)
-	    || (get_comdat_group ()
-		&& resolution != LDPR_PREVAILING_DEF
-		&& resolution != LDPR_PREVAILING_DEF_IRONLY
-		&& resolution != LDPR_PREVAILING_DEF_IRONLY_EXP));
+	    || ((get_comdat_group ()
+		 || DECL_COMMON (decl)
+		 || (DECL_SECTION_NAME (decl) && DECL_WEAK (decl)))
+		&& ((resolution != LDPR_PREVAILING_DEF
+		     && resolution != LDPR_PREVAILING_DEF_IRONLY_EXP)
+		    || flag_incremental_link)
+		&& resolution != LDPR_PREVAILING_DEF_IRONLY));
   }
 
   /* Return true if NODE is local to a particular COMDAT group, and must not



More information about the Gcc-patches mailing list