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]

Weakref and cgraph part 1


Hi,
this patch makes cgraph code to also handle wekrefs as long as their
destination declaration is known.  The cases where it is not still needs
updating at lto-symtab I plan to do incrementally.

The basic idea is to handle weakrefs as external declaration (so they
are subject of unrechable code removal) and make cgraph code to output
those that are still needed.

I had this in my tree for a while, so hope it will not cause much surprises.
Bootstrapped/regtested x86_64-linux & tested on Mozilla/libreoffice LTO

Honza

	* cgraphunit.c (handle_alias_pairs): Also handle wekref with destination
	declared.
	(output_weakrefs): New function.
	* varpool.c (varpool_create_variable_alias): Handle external aliases.
Index: cgraphunit.c
===================================================================
*** cgraphunit.c	(revision 180053)
--- cgraphunit.c	(working copy)
*************** handle_alias_pairs (void)
*** 1219,1225 ****
    for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
      {
        if (TREE_CODE (p->decl) == FUNCTION_DECL
- 	   && !lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))
  	  && (target_node = cgraph_node_for_asm (p->target)) != NULL)
  	{
  	  src_node = cgraph_get_node (p->decl);
--- 1219,1224 ----
*************** handle_alias_pairs (void)
*** 1231,1242 ****
  	     However for weakref we insist on EXTERNAL flag being set.
  	     See gcc.dg/attr-alias-5.c  */
  	  if (DECL_EXTERNAL (p->decl))
! 	    DECL_EXTERNAL (p->decl) = 0;
  	  cgraph_create_function_alias (p->decl, target_node->decl);
  	  VEC_unordered_remove (alias_pair, alias_pairs, i);
  	}
        else if (TREE_CODE (p->decl) == VAR_DECL
- 	       && !lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))
  	       && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
  	{
  	  /* Normally EXTERNAL flag is used to mark external inlines,
--- 1230,1241 ----
  	     However for weakref we insist on EXTERNAL flag being set.
  	     See gcc.dg/attr-alias-5.c  */
  	  if (DECL_EXTERNAL (p->decl))
! 	    DECL_EXTERNAL (p->decl) = lookup_attribute ("weakref",
! 							DECL_ATTRIBUTES (p->decl)) != NULL;
  	  cgraph_create_function_alias (p->decl, target_node->decl);
  	  VEC_unordered_remove (alias_pair, alias_pairs, i);
  	}
        else if (TREE_CODE (p->decl) == VAR_DECL
  	       && (target_vnode = varpool_node_for_asm (p->target)) != NULL)
  	{
  	  /* Normally EXTERNAL flag is used to mark external inlines,
*************** handle_alias_pairs (void)
*** 1245,1251 ****
  	     However for weakref we insist on EXTERNAL flag being set.
  	     See gcc.dg/attr-alias-5.c  */
  	  if (DECL_EXTERNAL (p->decl))
! 	    DECL_EXTERNAL (p->decl) = 0;
  	  varpool_create_variable_alias (p->decl, target_vnode->decl);
  	  VEC_unordered_remove (alias_pair, alias_pairs, i);
  	}
--- 1244,1251 ----
  	     However for weakref we insist on EXTERNAL flag being set.
  	     See gcc.dg/attr-alias-5.c  */
  	  if (DECL_EXTERNAL (p->decl))
! 	    DECL_EXTERNAL (p->decl) = lookup_attribute ("weakref",
! 							DECL_ATTRIBUTES (p->decl)) != NULL;
  	  varpool_create_variable_alias (p->decl, target_vnode->decl);
  	  VEC_unordered_remove (alias_pair, alias_pairs, i);
  	}
*************** ipa_passes (void)
*** 2064,2069 ****
--- 2064,2089 ----
    bitmap_obstack_release (NULL);
  }
  
+ /* Weakrefs may be associated to external decls and thus not output
+    at expansion time.  Emit all neccesary aliases.  */
+ 
+ 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)
+         && !TREE_ASM_WRITTEN (node->decl))
+       assemble_alias (node->decl,
+ 		      DECL_ASSEMBLER_NAME (node->thunk.alias));
+   for (vnode = varpool_nodes; vnode; vnode = vnode->next)
+     if (vnode->alias && vnode->alias_of && DECL_EXTERNAL (vnode->decl)
+         && !TREE_ASM_WRITTEN (vnode->decl))
+       assemble_alias (vnode->decl,
+ 		      DECL_ASSEMBLER_NAME (vnode->alias_of));
+ }
+ 
  
  /* Perform simple optimizations based on callgraph.  */
  
*************** cgraph_optimize (void)
*** 2150,2155 ****
--- 2170,2177 ----
  
        varpool_assemble_pending_decls ();
      }
+ 
+   output_weakrefs ();
    cgraph_process_new_functions ();
    cgraph_state = CGRAPH_STATE_FINISHED;
  
Index: varpool.c
===================================================================
*** varpool.c	(revision 180052)
--- varpool.c	(working copy)
*************** varpool_create_variable_alias (tree alia
*** 703,711 ****
    gcc_assert (TREE_CODE (alias) == VAR_DECL);
    alias_node = varpool_node (alias);
    alias_node->alias = 1;
!   alias_node->finalized = 1;
    alias_node->alias_of = decl;
!   if (decide_is_variable_needed (alias_node, alias)
        || alias_node->needed)
      varpool_mark_needed_node (alias_node);
    return alias_node;
--- 703,713 ----
    gcc_assert (TREE_CODE (alias) == VAR_DECL);
    alias_node = varpool_node (alias);
    alias_node->alias = 1;
!   if (!DECL_EXTERNAL (alias))
!     alias_node->finalized = 1;
    alias_node->alias_of = decl;
!   if ((!DECL_EXTERNAL (alias)
!        && decide_is_variable_needed (alias_node, alias))
        || alias_node->needed)
      varpool_mark_needed_node (alias_node);
    return alias_node;


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