Hi,
this patch removes code handling alias pairs after they was taken over by 
symbol table.
It also streamlines how things are output - do_assemble_alias is called when 
alias should
be output now, while assemble_alias is the function registering new alias into 
symbol
table.

I think I will rename these incrementaly.

Bootstrapped/regtested x86_64-linux

        * tree.h (alias_diag_flags): Remove.
        (alias_pair): Remove emitted_diags.
        (finish_aliases_1, finish_aliases_2, remove_unreachable_alias_pairs,
        symbol_alias_set_t, symbol_alias_set_destroy,
        symbol_alias_set_contains, propagate_aliases_backward): Remove.
        * toplev.c (compile_file): Do not call finish_aliases_2
        * cgraphunit.c (cgraph_process_new_functions): Do not call 
finish_aliases_1.
        (handle_alias_pairs): Output diagnostics about aliases to externals.
        (assemble_thunks_and_aliases): Use do_assemble_alias.
        (output_weakrefs): Likewise.
        (finalize_compilation_unit): Do not call finish_aliases_1.
        * ipa.c (symtab_remove_unreachable_nodes): De not call 
remove_unreachable_alias_pairs.
        * varasm.c (do_assemble_alias): Export.
        (symbol_alias_set_create, symbol_alias_set_destroy, 
symbol_alias_set_contains,
        symbol_alias_set_insert, propagate_aliases_forward, 
propagate_aliases_backward,
        propagate_aliases_backward, trivially_visible_alias, 
trivially_defined_alias,
        remove_unreachable_alias_pairs, finish_aliases_1, finish_aliases_2, 
        assemble_alias): Remove.
        * output.h (do_assemble_alias): Declare.
        * varpool.c (varpool_remove_unreferenced_decls): Do not call 
finish_aliases_1.
Index: tree.h
===================================================================
*** tree.h      (revision 187695)
--- tree.h      (working copy)
*************** extern const unsigned char tree_code_len
*** 239,263 ****
  
  extern const char *const tree_code_name[];
  
! /* We have to be able to tell cgraph about the needed-ness of the target
!    of an alias.  This requires that the decl have been defined.  Aliases
!    that precede their definition have to be queued for later processing.  */
! 
! /* The deferred processing proceeds in several passes.  We memorize the
!    diagnostics emitted for a pair to prevent repeating messages when the
!    queue gets re-scanned after possible updates.  */
! 
! typedef enum {
!   ALIAS_DIAG_NONE      = 0x0,
!   ALIAS_DIAG_TO_UNDEF  = 0x1,
!   ALIAS_DIAG_TO_EXTERN = 0x2
! } alias_diag_flags;
!   
  typedef struct GTY(()) alias_pair
  {
    tree decl;
    tree target;  
-   int  emitted_diags;  /* alias_diags already emitted for this pair.  */
  } alias_pair;
  
  /* Define gc'd vector type.  */
--- 239,252 ----
  
  extern const char *const tree_code_name[];
  
! /* When procesing aliases on symtab level, we need the declaration of target.
!    For this reason we need to queue aliases and process them after all 
declarations
!    has been produced.  */
! 
  typedef struct GTY(()) alias_pair
  {
    tree decl;
    tree target;  
  } alias_pair;
  
  /* Define gc'd vector type.  */
*************** extern void mark_decl_referenced (tree);
*** 5686,5709 ****
  extern void notice_global_symbol (tree);
  extern void set_user_assembler_name (tree, const char *);
  extern void process_pending_assemble_externals (void);
- extern void finish_aliases_1 (void);
- extern void finish_aliases_2 (void);
- extern void remove_unreachable_alias_pairs (void);
  extern bool decl_replaceable_p (tree);
  extern bool decl_binds_to_current_def_p (tree);
- 
- /* Derived type for use by compute_visible_aliases and callers.  A symbol
-    alias set is a pointer set into which we enter IDENTIFIER_NODES bearing
-    the canonicalised assembler-level symbol names corresponding to decls
-    and their aliases.  */
- typedef struct pointer_set_t symbol_alias_set_t;
- 
- extern void symbol_alias_set_destroy (symbol_alias_set_t *);
- extern int symbol_alias_set_contains (const symbol_alias_set_t *, tree);
- extern symbol_alias_set_t * propagate_aliases_backward (bool (*)
-                                                        (tree, tree, void *),
-                                                       void *);
- 
  /* In stmt.c */
  extern void expand_computed_goto (tree);
  extern bool parse_output_constraint (const char **, int, int, int,
--- 5675,5682 ----
Index: toplev.c
===================================================================
*** toplev.c    (revision 187695)
--- toplev.c    (working copy)
*************** compile_file (void)
*** 577,584 ****
       basically finished.  */
    if (in_lto_p || !flag_lto || flag_fat_lto_objects)
      {
-       finish_aliases_2 ();
- 
        /* Likewise for mudflap static object registrations.  */
        if (flag_mudflap)
        mudflap_finish_file ();
--- 577,582 ----
Index: cgraphunit.c
===================================================================
*** cgraphunit.c        (revision 187695)
--- cgraphunit.c        (working copy)
*************** cgraph_process_new_functions (void)
*** 285,291 ****
  
    if (!cgraph_new_nodes)
      return false;
-   finish_aliases_1 ();
    handle_alias_pairs ();
    /*  Note that this queue may grow as its being processed, as the new
        functions may generate new ones.  */
--- 285,290 ----
*************** handle_alias_pairs (void)
*** 1068,1073 ****
--- 1070,1087 ----
          = lookup_attribute ("weakref",
                              DECL_ATTRIBUTES (p->decl)) != NULL;
  
+       if (DECL_EXTERNAL (target_node->symbol.decl)
+         /* We use local aliases for C++ thunks to force the tailcall
+            to bind locally.  This is a hack - to keep it working do
+            the following (which is not strictly correct).  */
+         && (! TREE_CODE (target_node->symbol.decl) == FUNCTION_DECL
+             || ! DECL_VIRTUAL_P (target_node->symbol.decl))
+         && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
+       {
+         error ("%q+D aliased to external symbol %qE",
+                p->decl, p->target);
+       }
+ 
        if (TREE_CODE (p->decl) == FUNCTION_DECL
            && target_node && symtab_function_p (target_node))
        {
*************** assemble_thunks_and_aliases (struct cgra
*** 1552,1559 ****
        /* Force assemble_alias to really output the alias this time instead
           of buffering it in same alias pairs.  */
        TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
!       assemble_alias (alias->symbol.decl,
!                       DECL_ASSEMBLER_NAME (alias->thunk.alias));
        assemble_thunks_and_aliases (alias);
        TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
        }
--- 1566,1573 ----
        /* Force assemble_alias to really output the alias this time instead
           of buffering it in same alias pairs.  */
        TREE_ASM_WRITTEN (alias->thunk.alias) = 1;
!       do_assemble_alias (alias->symbol.decl,
!                          DECL_ASSEMBLER_NAME (alias->thunk.alias));
        assemble_thunks_and_aliases (alias);
        TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written;
        }
*************** output_weakrefs (void)
*** 1902,1917 ****
      if (node->alias && DECL_EXTERNAL (node->symbol.decl)
          && !TREE_ASM_WRITTEN (node->symbol.decl)
        && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
!       assemble_alias (node->symbol.decl,
!                     node->thunk.alias ? DECL_ASSEMBLER_NAME 
(node->thunk.alias)
!                     : get_alias_symbol (node->symbol.decl));
    FOR_EACH_VARIABLE (vnode)
      if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
          && !TREE_ASM_WRITTEN (vnode->symbol.decl)
        && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
!       assemble_alias (vnode->symbol.decl,
!                     vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
!                     : get_alias_symbol (vnode->symbol.decl));
  }
  
  /* Initialize callgraph dump file.  */
--- 1916,1931 ----
      if (node->alias && DECL_EXTERNAL (node->symbol.decl)
          && !TREE_ASM_WRITTEN (node->symbol.decl)
        && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
!       do_assemble_alias (node->symbol.decl,
!                        node->thunk.alias ? DECL_ASSEMBLER_NAME 
(node->thunk.alias)
!                        : get_alias_symbol (node->symbol.decl));
    FOR_EACH_VARIABLE (vnode)
      if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
          && !TREE_ASM_WRITTEN (vnode->symbol.decl)
        && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
!       do_assemble_alias (vnode->symbol.decl,
!                        vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
!                        : get_alias_symbol (vnode->symbol.decl));
  }
  
  /* Initialize callgraph dump file.  */
*************** finalize_compilation_unit (void)
*** 2058,2064 ****
    finalize_size_functions ();
  
    /* Mark alias targets necessary and emit diagnostics.  */
-   finish_aliases_1 ();
    handle_alias_pairs ();
  
    if (!quiet_flag)
--- 2072,2077 ----
*************** finalize_compilation_unit (void)
*** 2075,2081 ****
    cgraph_analyze_functions ();
  
    /* Mark alias targets necessary and emit diagnostics.  */
-   finish_aliases_1 ();
    handle_alias_pairs ();
  
    /* Gimplify and lower thunks.  */
--- 2088,2093 ----
Index: ipa.c
===================================================================
*** ipa.c       (revision 187695)
--- ipa.c       (working copy)
*************** symtab_remove_unreachable_nodes (bool be
*** 454,463 ****
      FOR_EACH_DEFINED_FUNCTION (node)
        cgraph_propagate_frequency (node);
  
-   /* Reclaim alias pairs for functions that have disappeared from the
-      call graph.  */
-   remove_unreachable_alias_pairs ();
- 
    return changed;
  }
  
--- 454,459 ----
Index: varasm.c
===================================================================
*** varasm.c    (revision 187695)
--- varasm.c    (working copy)
*************** VEC(alias_pair,gc) *alias_pairs;
*** 5435,5441 ****
     or ASM_OUTPUT_DEF_FROM_DECLS.  The function defines the symbol whose
     tree node is DECL to have the value of the tree node TARGET.  */
  
! static void
  do_assemble_alias (tree decl, tree target)
  {
    /* Emulated TLS had better not get this var.  */
--- 5435,5441 ----
     or ASM_OUTPUT_DEF_FROM_DECLS.  The function defines the symbol whose
     tree node is DECL to have the value of the tree node TARGET.  */
  
! void
  do_assemble_alias (tree decl, tree target)
  {
    /* Emulated TLS had better not get this var.  */
*************** do_assemble_alias (tree decl, tree targe
*** 5535,5789 ****
  #endif
  }
  
- 
- /* Allocate and construct a symbol alias set.  */
- 
- static symbol_alias_set_t *
- symbol_alias_set_create (void)
- {
-   return pointer_set_create ();
- }
- 
- /* Destruct and free a symbol alias set.  */
- 
- void
- symbol_alias_set_destroy (symbol_alias_set_t *aset)
- {
-   pointer_set_destroy (aset);
- }
- 
- /* Test if a symbol alias set contains a given name.  */
- 
- int
- symbol_alias_set_contains (const symbol_alias_set_t *aset, tree t)
- {
-   /* We accept either a DECL or an IDENTIFIER directly.  */
-   if (TREE_CODE (t) != IDENTIFIER_NODE)
-     t = DECL_ASSEMBLER_NAME (t);
-   t = targetm.asm_out.mangle_assembler_name (IDENTIFIER_POINTER (t));
-   return pointer_set_contains (aset, t);
- }
- 
- /* Enter a new name into a symbol alias set.  */
- 
- static int
- symbol_alias_set_insert (symbol_alias_set_t *aset, tree t)
- {
-   /* We accept either a DECL or an IDENTIFIER directly.  */
-   if (TREE_CODE (t) != IDENTIFIER_NODE)
-     t = DECL_ASSEMBLER_NAME (t);
-   t = targetm.asm_out.mangle_assembler_name (IDENTIFIER_POINTER (t));
-   return pointer_set_insert (aset, t);
- }
- 
- /* IN_SET_P is a predicate function assuming to be taken
-    alias_pair->decl, alias_pair->target and DATA arguments.
- 
-    Compute set of aliases by including everything where TRIVIALLY_VISIBLE
-    predeicate is true and propagate across aliases such that when
-    alias DECL is included, its TARGET is included too.  */
- 
- static symbol_alias_set_t *
- propagate_aliases_forward (bool (*in_set_p)
-                            (tree decl, tree target, void *data),
-                          void *data)
- {
-   symbol_alias_set_t *set;
-   unsigned i;
-   alias_pair *p;
-   bool changed;
- 
-   set = symbol_alias_set_create ();
-   for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i)
-     if (in_set_p (p->decl, p->target, data))
-       symbol_alias_set_insert (set, p->decl);
-   do
-     {
-       changed = false;
-       for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i)
-       if (symbol_alias_set_contains (set, p->decl)
-           && !symbol_alias_set_insert (set, p->target))
-         changed = true;
-     }
-   while (changed);
- 
-   return set;
- }
- 
- /* Like propagate_aliases_forward but do backward propagation.  */
- 
- symbol_alias_set_t *
- propagate_aliases_backward (bool (*in_set_p)
-                            (tree decl, tree target, void *data),
-                          void *data)
- {
-   symbol_alias_set_t *set;
-   unsigned i;
-   alias_pair *p;
-   bool changed;
- 
-   /* We have to compute the set of set nodes including aliases
-      themselves.  */
-   set = symbol_alias_set_create ();
-   for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i)
-     if (in_set_p (p->decl, p->target, data))
-       symbol_alias_set_insert (set, p->target);
-   do
-     {
-       changed = false;
-       for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i)
-       if (symbol_alias_set_contains (set, p->target)
-           && !symbol_alias_set_insert (set, p->decl))
-         changed = true;
-     }
-   while (changed);
- 
-   return set;
- }
- /* See if the alias is trivially visible.  This means
-      1) alias is expoerted from the unit or
-      2) alias is used in the code.
-    We assume that unused cgraph/varpool nodes has been
-    removed.
-    Used as callback for propagate_aliases.  */
- 
- static bool
- trivially_visible_alias (tree decl, tree target ATTRIBUTE_UNUSED,
-                        void *data ATTRIBUTE_UNUSED)
- {
-   struct cgraph_node *fnode = NULL;
-   struct varpool_node *vnode = NULL;
- 
-   if (!TREE_PUBLIC (decl))
-     {
-       if (TREE_CODE (decl) == FUNCTION_DECL)
-       fnode = cgraph_get_node (decl);
-       else
-       vnode = varpool_get_node (decl);
-       return vnode || fnode;
-     }
-   else
-     return true;
- }
- 
- /* See if the target of alias is defined in this unit.
-    Used as callback for propagate_aliases.  */
- 
- static bool
- trivially_defined_alias (tree decl ATTRIBUTE_UNUSED,
-                        tree target,
-                        void *data ATTRIBUTE_UNUSED)
- {
-   struct cgraph_node *fnode = NULL;
-   struct varpool_node *vnode = NULL;
- 
-   fnode = cgraph_node_for_asm (target);
-   vnode = (fnode == NULL) ? varpool_node_for_asm (target) : NULL;
-   return (fnode && fnode->analyzed) || (vnode && vnode->finalized);
- }
- 
- /* Remove the alias pairing for functions that are no longer in the call
-    graph.  */
- 
- void
- remove_unreachable_alias_pairs (void)
- {
-   symbol_alias_set_t *visible;
-   unsigned i;
-   alias_pair *p;
- 
-   if (alias_pairs == NULL)
-     return;
- 
-   /* We have to compute the set of visible nodes including aliases
-      themselves.  */
-   visible = propagate_aliases_forward (trivially_visible_alias, NULL);
- 
-   for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); )
-     {
-       if (!DECL_EXTERNAL (p->decl)
-         && !symbol_alias_set_contains (visible, p->decl))
-       {
-         VEC_unordered_remove (alias_pair, alias_pairs, i);
-         continue;
-       }
- 
-       i++;
-     }
- 
-   symbol_alias_set_destroy (visible);
- }
- 
- 
- /* First pass of completing pending aliases.  Make sure that cgraph knows
-    which symbols will be required.  */
- 
- void
- finish_aliases_1 (void)
- {
-   symbol_alias_set_t *defined;
-   unsigned i;
-   alias_pair *p;
- 
-   if (alias_pairs == NULL)
-     return;
- 
-   /* We have to compute the set of defined nodes including aliases
-      themselves.  */
-   defined = propagate_aliases_backward (trivially_defined_alias, NULL);
- 
-   FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
-     {
-       tree target_decl;
- 
-       target_decl = find_decl (p->target);
-       if (target_decl == NULL)
-       {
-         if (symbol_alias_set_contains (defined, p->target))
-           continue;
- 
-         if (! (p->emitted_diags & ALIAS_DIAG_TO_UNDEF)
-             && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
-           {
-             error ("%q+D aliased to undefined symbol %qE",
-                    p->decl, p->target);
-             p->emitted_diags |= ALIAS_DIAG_TO_UNDEF;
-           }
-       }
-       else if (! (p->emitted_diags & ALIAS_DIAG_TO_EXTERN)
-              && DECL_EXTERNAL (target_decl)
-              /* We use local aliases for C++ thunks to force the tailcall
-                 to bind locally.  This is a hack - to keep it working do
-                 the following (which is not strictly correct).  */
-              && (! TREE_CODE (target_decl) == FUNCTION_DECL
-                  || ! DECL_VIRTUAL_P (target_decl))
-              && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
-       {
-         error ("%q+D aliased to external symbol %qE",
-                p->decl, p->target);
-         p->emitted_diags |= ALIAS_DIAG_TO_EXTERN;
-       }
-     }
- 
-   symbol_alias_set_destroy (defined);
- }
- 
- /* Second pass of completing pending aliases.  Emit the actual assembly.
-    This happens at the end of compilation and thus it is assured that the
-    target symbol has been emitted.  */
- 
- void
- finish_aliases_2 (void)
- {
-   unsigned i;
-   alias_pair *p;
- 
-   FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
-     do_assemble_alias (p->decl, p->target);
- 
-   VEC_truncate (alias_pair, alias_pairs, 0);
- }
- 
  /* Emit an assembler directive to make the symbol for DECL an alias to
     the symbol for TARGET.  */
  
--- 5535,5540 ----
*************** assemble_alias (tree decl, tree target)
*** 5845,5858 ****
      target_decl = find_decl (target);
    else
      target_decl= NULL;
!   if (target_decl && TREE_ASM_WRITTEN (target_decl))
      do_assemble_alias (decl, target);
    else
      {
        alias_pair *p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL);
        p->decl = decl;
        p->target = target;
-       p->emitted_diags = ALIAS_DIAG_NONE;
      }
  }
  
--- 5596,5609 ----
      target_decl = find_decl (target);
    else
      target_decl= NULL;
!   if ((target_decl && TREE_ASM_WRITTEN (target_decl))
!       || cgraph_state >= CGRAPH_STATE_EXPANSION)
      do_assemble_alias (decl, target);
    else
      {
        alias_pair *p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL);
        p->decl = decl;
        p->target = target;
      }
  }
  
Index: output.h
===================================================================
*** output.h    (revision 187695)
--- output.h    (working copy)
*************** extern int decode_reg_name (const char *
*** 187,192 ****
--- 187,193 ----
  extern int decode_reg_name_and_count (const char *, int *);
  
  extern void assemble_alias (tree, tree);
+ extern void do_assemble_alias (tree, tree);
  
  extern void default_assemble_visibility (tree, int);
  
Index: varpool.c
===================================================================
*** varpool.c   (revision 187695)
--- varpool.c   (working copy)
*************** varpool_remove_unreferenced_decls (void)
*** 349,355 ****
  
    if (cgraph_dump_file)
      fprintf (cgraph_dump_file, "Trivially needed variables:");
-   finish_aliases_1 ();
    FOR_EACH_DEFINED_VARIABLE (node)
      {
        if (node->analyzed
--- 349,354 ----

Reply via email to