re PR ipa/65005 (FAIL: c-c++-common/torture/builtin-arith-overflow-12.c)
authorJan Hubicka <hubicka@ucw.cz>
Wed, 11 Feb 2015 09:11:06 +0000 (10:11 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 11 Feb 2015 09:11:06 +0000 (09:11 +0000)
PR ipa/65005
* ipa-visibility.c (cgraph_node::non_local_p): Turn into static
function.
* symtab.c (symtab_node::verify_base): Remove check that non-definitions
have no comdat group.
* lto-cgraph.c (lto_output_node): Always output thunk and alias info.
(lto_output_varpool_node): Always output alias info.
(output_refs): Output refs of boundary aliases, too.
(compute_ltrans_boundary): Add alias and thunk target into boundaries.
(output_symtab): Output call eges in thunks in boundary.
(get_alias_symbol): Remove.
(input_node, input_varpool_node): Do not special case weakrefs.
* ipa.c (symbol_table::remove_unreachable_nodes): Do not remove
alias and thunks targets in the boundary; do not take removed symbols
from their comdat groups.
* cgraph.c (cgraph_node::local_info): Look through aliases and thunks.
(cgraph_node::global_info): Remove.
(cgraph_node::rtl_info): Look through aliases and thunks.
* cgrpah.h (global_info): Remove.
(non_local_p): Remove.

From-SVN: r220608

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-visibility.c
gcc/ipa.c
gcc/lto-cgraph.c
gcc/symtab.c

index a409b164878be2726f654d38b0361ae8d1d0522a..c9e0a22552cdd1e310cfd59cbaf8575d0054d717 100644 (file)
@@ -1,3 +1,26 @@
+2015-02-10  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/65005
+       * ipa-visibility.c (cgraph_node::non_local_p): Turn into static
+       function.
+       * symtab.c (symtab_node::verify_base): Remove check that non-definitions
+       have no comdat group.
+       * lto-cgraph.c (lto_output_node): Always output thunk and alias info.
+       (lto_output_varpool_node): Always output alias info.
+       (output_refs): Output refs of boundary aliases, too.
+       (compute_ltrans_boundary): Add alias and thunk target into boundaries.
+       (output_symtab): Output call eges in thunks in boundary.
+       (get_alias_symbol): Remove.
+       (input_node, input_varpool_node): Do not special case weakrefs.
+       * ipa.c (symbol_table::remove_unreachable_nodes): Do not remove
+       alias and thunks targets in the boundary; do not take removed symbols
+       from their comdat groups.
+       * cgraph.c (cgraph_node::local_info): Look through aliases and thunks.
+       (cgraph_node::global_info): Remove.
+       (cgraph_node::rtl_info): Look through aliases and thunks.
+       * cgrpah.h (global_info): Remove.
+       (non_local_p): Remove.
+
 2015-02-10  David Wohlferd  <dw@LimeGreenSocks.com>
            Sandra Loosemore  <sandra@codesourcery.com>
 
index 8ea8ae937142a6b439cfde9b7ded2ceee390a7ec..a71f68ca4e0c692379a0c662f2799a0adbec6c0f 100644 (file)
@@ -1846,20 +1846,7 @@ cgraph_node::local_info (tree decl)
   cgraph_node *node = get (decl);
   if (!node)
     return NULL;
-  return &node->local;
-}
-
-/* Return global info for the compiled function.  */
-
-cgraph_global_info *
-cgraph_node::global_info (tree decl)
-{
-  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
-    && symtab->global_info_ready);
-  cgraph_node *node = get (decl);
-  if (!node)
-    return NULL;
-  return &node->global;
+  return &node->ultimate_alias_target ()->local;
 }
 
 /* Return local info for the compiled function.  */
@@ -1869,11 +1856,13 @@ cgraph_node::rtl_info (tree decl)
 {
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
   cgraph_node *node = get (decl);
-  if (!node
-      || (decl != current_function_decl
-         && !TREE_ASM_WRITTEN (node->decl)))
+  if (!node)
+    return NULL;
+  node = node->ultimate_alias_target ();
+  if (node->decl != current_function_decl
+      && !TREE_ASM_WRITTEN (node->decl))
     return NULL;
-  return &node->rtl;
+  return &node->ultimate_alias_target ()->rtl;
 }
 
 /* Return a string describing the failure REASON.  */
index 0fdb459ab00917b483a519d1eeed3e92fac18714..b9a276c3715d5e993728e19cb5020790f999400a 100644 (file)
@@ -1164,9 +1164,6 @@ public:
   /* Return local info for the compiled function.  */
   static cgraph_local_info *local_info (tree decl);
 
-  /* Return global info for the compiled function.  */
-  static cgraph_global_info *global_info (tree);
-
   /* Return local info for the compiled function.  */
   static cgraph_rtl_info *rtl_info (tree);
 
@@ -1187,10 +1184,6 @@ public:
     return node->used_from_object_file_p ();
   }
 
-  /* Return true when cgraph_node can not be local.
-     Worker for cgraph_local_node_p.  */
-  static bool non_local_p (cgraph_node *node, void *);
-
   /* Verify whole cgraph structure.  */
   static void DEBUG_FUNCTION verify_cgraph_nodes (void);
 
index a8ac971b848068cd754f21876e130f960e3e349d..c33ee469dbe96cf3873c3dc60901175a002662d9 100644 (file)
@@ -101,8 +101,8 @@ along with GCC; see the file COPYING3.  If not see
 
 /* Return true when NODE can not be local. Worker for cgraph_local_node_p.  */
 
-bool
-cgraph_node::non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+static bool
+non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
 {
   return !(node->only_called_directly_or_aliased_p ()
           /* i386 would need update to output thunk with locak calling
@@ -124,7 +124,7 @@ cgraph_node::local_p (void)
 
    if (n->thunk.thunk_p)
      return n->callees->callee->local_p ();
-   return !n->call_for_symbol_thunks_and_aliases (cgraph_node::non_local_p,
+   return !n->call_for_symbol_thunks_and_aliases (non_local_p,
                                                  NULL, true);
                                        
 }
index 9cbd2da8023678689f914d32f4a43156f5b460b3..620431c54d6b1c2c7b86c877ab18aea3010daec9 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -383,7 +383,11 @@ symbol_table::remove_unreachable_nodes (FILE *file)
       /* If we are processing symbol in boundary, mark its AUX pointer for
         possible later re-processing in enqueue_node.  */
       if (in_boundary_p)
-       node->aux = (void *)2;
+       {
+         node->aux = (void *)2;
+         if (node->alias && node->analyzed)
+           enqueue_node (node->get_alias_target (), &first, &reachable);
+       }
       else
        {
          if (TREE_CODE (node->decl) == FUNCTION_DECL
@@ -486,6 +490,9 @@ symbol_table::remove_unreachable_nodes (FILE *file)
                }
 
            }
+         else if (cnode->thunk.thunk_p)
+           enqueue_node (cnode->callees->callee, &first, &reachable);
+             
          /* If any reachable function has simd clones, mark them as
             reachable as well.  */
          if (cnode->simd_clones)
@@ -534,7 +541,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
            node->release_body ();
          else if (!node->clone_of)
            gcc_assert (in_lto_p || DECL_RESULT (node->decl));
-         if (node->definition)
+         if (node->definition && !node->alias && !node->thunk.thunk_p)
            {
              if (file)
                fprintf (file, " %s/%i", node->name (), node->order);
@@ -554,7 +561,6 @@ symbol_table::remove_unreachable_nodes (FILE *file)
              if (!node->in_other_partition)
                node->local.local = false;
              node->remove_callees ();
-             node->remove_from_same_comdat_group ();
              node->remove_all_references ();
              changed = true;
              if (node->thunk.thunk_p
@@ -614,7 +620,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
          vnode->remove ();
          changed = true;
        }
-      else if (!reachable.contains (vnode))
+      else if (!reachable.contains (vnode) && !vnode->alias)
         {
          tree init;
          if (vnode->definition)
index ab9524b3b73fd4272ee4992e3bd124db337d0dea..c0fa47d2c25aea672f4bd10229afddc02a974415 100644 (file)
@@ -432,14 +432,13 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
   struct cgraph_node *clone_of, *ultimate_clone_of;
   ipa_opt_pass_d *pass;
   int i;
-  bool alias_p;
   const char *comdat;
   const char *section;
   tree group;
 
   boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
 
-  if (node->analyzed && !boundary_p)
+  if (node->analyzed && (!boundary_p || node->alias || node->thunk.thunk_p))
     tag = LTO_symtab_analyzed_node;
   else
     tag = LTO_symtab_unavail_node;
@@ -565,14 +564,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
                     || referenced_from_other_partition_p (node, encoder)), 1);
   bp_pack_value (&bp, node->lowered, 1);
   bp_pack_value (&bp, in_other_partition, 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.  */
-  alias_p = node->alias && (!boundary_p || node->weakref);
-  bp_pack_value (&bp, alias_p, 1);
+  bp_pack_value (&bp, node->alias, 1);
   bp_pack_value (&bp, node->weakref, 1);
   bp_pack_value (&bp, node->frequency, 2);
   bp_pack_value (&bp, node->only_called_at_startup, 1);
@@ -581,14 +573,14 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
   bp_pack_value (&bp, node->calls_comdat_local, 1);
   bp_pack_value (&bp, node->icf_merged, 1);
   bp_pack_value (&bp, node->nonfreeing_fn, 1);
-  bp_pack_value (&bp, node->thunk.thunk_p && !boundary_p, 1);
+  bp_pack_value (&bp, node->thunk.thunk_p, 1);
   bp_pack_enum (&bp, ld_plugin_symbol_resolution,
                LDPR_NUM_KNOWN, node->resolution);
   bp_pack_value (&bp, node->instrumentation_clone, 1);
   streamer_write_bitpack (&bp);
   streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1);
 
-  if (node->thunk.thunk_p && !boundary_p)
+  if (node->thunk.thunk_p)
     {
       streamer_write_uhwi_stream
         (ob->main_stream,
@@ -618,7 +610,6 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
   bool boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
   struct bitpack_d bp;
   int ref;
-  bool alias_p;
   const char *comdat;
   const char *section;
   tree group;
@@ -638,8 +629,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
   bp_pack_value (&bp, node->implicit_section, 1);
   bp_pack_value (&bp, node->writeonly, 1);
   bp_pack_value (&bp, node->definition, 1);
-  alias_p = node->alias && (!boundary_p || node->weakref);
-  bp_pack_value (&bp, alias_p, 1);
+  bp_pack_value (&bp, node->alias, 1);
   bp_pack_value (&bp, node->weakref, 1);
   bp_pack_value (&bp, node->analyzed && !boundary_p, 1);
   gcc_assert (node->definition || !node->analyzed);
@@ -794,18 +784,18 @@ output_outgoing_cgraph_edges (struct cgraph_edge *edge,
 static void
 output_refs (lto_symtab_encoder_t encoder)
 {
-  lto_symtab_encoder_iterator lsei;
   struct lto_simple_output_block *ob;
   int count;
   struct ipa_ref *ref;
-  int i;
 
   ob = lto_create_simple_output_block (LTO_section_refs);
 
-  for (lsei = lsei_start_in_partition (encoder); !lsei_end_p (lsei);
-       lsei_next_in_partition (&lsei))
+  for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
-      symtab_node *node = lsei_node (lsei);
+      symtab_node *node = lto_symtab_encoder_deref (encoder, i);
+
+      if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node))
+       continue;
 
       count = node->ref_list.nreferences ();
       if (count)
@@ -813,7 +803,7 @@ output_refs (lto_symtab_encoder_t encoder)
          streamer_write_gcov_count_stream (ob->main_stream, count);
          streamer_write_uhwi_stream (ob->main_stream,
                                     lto_symtab_encoder_lookup (encoder, node));
-         for (i = 0; node->iterate_reference (i, ref); i++)
+         for (int i = 0; node->iterate_reference (i, ref); i++)
            lto_output_ref (ob, ref, encoder);
        }
     }
@@ -987,6 +977,19 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
                }
            }
     }
+  /* Be sure to also insert alias targert and thunk callees.  These needs
+     to stay to aid local calling conventions.  */
+  for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
+    {
+      symtab_node *node = lto_symtab_encoder_deref (encoder, i);
+      cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+
+      if (node->alias && node->analyzed)
+       create_references (encoder, node);
+      if (cnode
+         && cnode->thunk.thunk_p)
+       add_node_to (encoder, cnode->callees->callee, false);
+    }
   lto_symtab_encoder_delete (in_encoder);
   return encoder;
 }
@@ -998,7 +1001,6 @@ output_symtab (void)
 {
   struct cgraph_node *node;
   struct lto_simple_output_block *ob;
-  lto_symtab_encoder_iterator lsei;
   int i, n_nodes;
   lto_symtab_encoder_t encoder;
 
@@ -1028,12 +1030,16 @@ output_symtab (void)
     }
 
   /* Go over the nodes in SET again to write edges.  */
-  for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
-       lsei_next_function_in_partition (&lsei))
+  for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
     {
-      node = lsei_cgraph_node (lsei);
-      output_outgoing_cgraph_edges (node->callees, ob, encoder);
-      output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder);
+      node = dyn_cast <cgraph_node *> (lto_symtab_encoder_deref (encoder, i));
+      if (node
+         && (node->thunk.thunk_p
+             || lto_symtab_encoder_in_partition_p (encoder, node)))
+       {
+         output_outgoing_cgraph_edges (node->callees, ob, encoder);
+         output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder);
+       }
     }
 
   streamer_write_uhwi_stream (ob->main_stream, 0);
index aba1ae4063bcff05c3ffeb99f91daa648ca0f359..3bfb04a25c12474f0702e22e75c55633248bee34 100644 (file)
@@ -1070,11 +1070,6 @@ symtab_node::verify_base (void)
          error ("same_comdat_group list across different groups");
          error_found = true;
        }
-      if (!n->definition)
-       {
-         error ("Node has same_comdat_group but it is not a definition");
-         error_found = true;
-       }
       if (n->type != type)
        {
          error ("mixing different types of symbol in same comdat groups is not supported");