This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Handle weakrefs from callgraph


Hi,
this patch makes weakref that has no declaration they alias to to go the callgraph
way instead of alias pair way.  This should make practically all sane aliases go
the callgraph way, but we still do not handle aliases from functions to variables
and vice versa.

They are not too hard to represent in callgraph+varpool but they complicate
handling of them.  I would think in favour of making them unsupported, but if neccesary,
I can add support for them.

Bootstrapped/regtested x86_64-linux, comitted.
Honza

	* cgraph.c (dump_cgraph_node): Dump alias flag.
	* cgraphunit.c (handle_alias_pairs): Handle weakrefs with no destination.
	(get_alias_symbol): New function.
	(output_weakrefs): Output also weakrefs with no destinatoin.
	(lto_output_node): Output weakref alias flag when at function boundary.
Index: cgraph.c
===================================================================
--- cgraph.c	(revision 180181)
+++ cgraph.c	(working copy)
@@ -1838,6 +1838,8 @@ dump_cgraph_node (FILE *f, struct cgraph
     fprintf (f, " only_called_at_startup");
   if (node->only_called_at_exit)
     fprintf (f, " only_called_at_exit");
+  else if (node->alias)
+    fprintf (f, " alias");
 
   fprintf (f, "\n");
 
Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 180181)
+++ cgraphunit.c	(working copy)
@@ -1249,6 +1249,18 @@ handle_alias_pairs (void)
 	  varpool_create_variable_alias (p->decl, target_vnode->decl);
 	  VEC_unordered_remove (alias_pair, alias_pairs, i);
 	}
+      /* Weakrefs with target not defined in current unit are easy to handle; they
+	 behave just as external variables except we need to note the alias flag
+	 to later output the weakref pseudo op into asm file.  */
+      else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
+	{
+	  if (TREE_CODE (p->decl) == FUNCTION_DECL)
+	    cgraph_get_create_node (p->decl)->alias = true;
+	  else
+	    varpool_get_node (p->decl)->alias = true;
+	  DECL_EXTERNAL (p->decl) = 1;
+	  VEC_unordered_remove (alias_pair, alias_pairs, i);
+	}
       else
 	{
 	  if (dump_file)
@@ -2064,24 +2078,36 @@ ipa_passes (void)
   bitmap_obstack_release (NULL);
 }
 
+/* Return string alias is alias of.  */
+
+static tree
+get_alias_symbol (tree decl)
+{
+  tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
+  return get_identifier (TREE_STRING_POINTER
+			  (TREE_VALUE (TREE_VALUE (alias))));
+}
+
 /* Weakrefs may be associated to external decls and thus not output
    at expansion time.  Emit all neccesary aliases.  */
 
-void
+static void
 output_weakrefs (void)
 {
   struct cgraph_node *node;
   struct varpool_node *vnode;
   for (node = cgraph_nodes; node; node = node->next)
-    if (node->alias && node->thunk.alias && DECL_EXTERNAL (node->decl)
+    if (node->alias && DECL_EXTERNAL (node->decl)
         && !TREE_ASM_WRITTEN (node->decl))
       assemble_alias (node->decl,
-		      DECL_ASSEMBLER_NAME (node->thunk.alias));
+		      node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
+		      : get_alias_symbol (node->decl));
   for (vnode = varpool_nodes; vnode; vnode = vnode->next)
-    if (vnode->alias && vnode->alias_of && DECL_EXTERNAL (vnode->decl)
+    if (vnode->alias && DECL_EXTERNAL (vnode->decl)
         && !TREE_ASM_WRITTEN (vnode->decl))
       assemble_alias (vnode->decl,
-		      DECL_ASSEMBLER_NAME (vnode->alias_of));
+		      vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
+		      : get_alias_symbol (vnode->decl));
 }
 
 
Index: lto-cgraph.c
===================================================================
--- lto-cgraph.c	(revision 180181)
+++ lto-cgraph.c	(working copy)
@@ -512,7 +512,13 @@ lto_output_node (struct lto_simple_outpu
 		     || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1);
   bp_pack_value (&bp, node->lowered, 1);
   bp_pack_value (&bp, in_other_partition, 1);
-  bp_pack_value (&bp, node->alias && !boundary_p, 1);
+  /* Real aliases in a boundary become non-aliases. However we still stream
+     alias info on weakrefs. 
+     TODO: We lose a bit of information here - when we know that variable is
+     defined in other unit, we may use the info on aliases to resolve 
+     symbol1 != symbol2 type tests that we can do only for locally defined objects
+     otherwise.  */
+  bp_pack_value (&bp, node->alias && (!boundary_p || DECL_EXTERNAL (node->decl)), 1);
   bp_pack_value (&bp, node->frequency, 2);
   bp_pack_value (&bp, node->only_called_at_startup, 1);
   bp_pack_value (&bp, node->only_called_at_exit, 1);
@@ -530,7 +536,8 @@ lto_output_node (struct lto_simple_outpu
       streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
       streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
     }
-  if ((node->alias || node->thunk.thunk_p) && !boundary_p)
+  if ((node->alias || node->thunk.thunk_p)
+      && (!boundary_p || (node->alias && DECL_EXTERNAL (node->decl))))
     {
       streamer_write_hwi_in_range (ob->main_stream, 0, 1,
 					node->thunk.alias != NULL);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]