[AArch64 Testsuite] vld1_lane.c: Remove unused test data
[platform/upstream/gcc.git] / gcc / ipa-comdats.c
index 6926900..e78ea35 100644 (file)
@@ -1,5 +1,5 @@
 /* Localize comdats.
-   Copyright (C) 2014 Free Software Foundation, Inc.
+   Copyright (C) 2014-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -52,10 +52,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "alias.h"
 #include "tree.h"
+#include "hard-reg-set.h"
+#include "function.h"
 #include "cgraph.h"
 #include "tree-pass.h"
-#include "pointer-set.h"
 
 /* Main dataflow loop propagating comdat groups across
    the symbol table.  All references to SYMBOL are examined
@@ -64,7 +66,7 @@ along with GCC; see the file COPYING3.  If not see
 
 tree
 propagate_comdat_group (struct symtab_node *symbol,
-                       tree newgroup, pointer_map <tree> &map)
+                       tree newgroup, hash_map<symtab_node *, tree> &map)
 {
   int i;
   struct ipa_ref *ref;
@@ -72,7 +74,7 @@ propagate_comdat_group (struct symtab_node *symbol,
   /* Walk all references to SYMBOL, recursively dive into aliases.  */
 
   for (i = 0;
-       ipa_ref_list_referring_iterate (&symbol->ref_list, i, ref)
+       symbol->iterate_referring (i, ref)
        && newgroup != error_mark_node; i++)
     {
       struct symtab_node *symbol2 = ref->referring;
@@ -105,7 +107,7 @@ propagate_comdat_group (struct symtab_node *symbol,
 
       /* The actual merge operation.  */
 
-      tree *val2 = map.contains (symbol2);
+      tree *val2 = map.get (symbol2);
 
       if (val2 && *val2 != newgroup)
        {
@@ -126,19 +128,21 @@ propagate_comdat_group (struct symtab_node *symbol,
       {
        struct symtab_node *symbol2 = edge->caller;
 
-       /* If we see inline clone, its comdat group actually
-          corresponds to the comdat group of the function it is inlined
-          to.  */
-
        if (cgraph_node * cn = dyn_cast <cgraph_node *> (symbol2))
          {
+           /* Thunks can not call across section boundary.  */
+           if (cn->thunk.thunk_p)
+             newgroup = propagate_comdat_group (symbol2, newgroup, map);
+           /* If we see inline clone, its comdat group actually
+              corresponds to the comdat group of the function it
+              is inlined to.  */
            if (cn->global.inlined_to)
              symbol2 = cn->global.inlined_to;
          }
 
         /* The actual merge operation.  */
 
-       tree *val2 = map.contains (symbol2);
+       tree *val2 = map.get (symbol2);
 
        if (val2 && *val2 != newgroup)
          {
@@ -161,11 +165,15 @@ enqueue_references (symtab_node **first,
                    symtab_node *symbol)
 {
   int i;
-  struct ipa_ref *ref;
+  struct ipa_ref *ref = NULL;
 
-  for (i = 0; ipa_ref_list_reference_iterate (&symbol->ref_list, i, ref); i++)
+  for (i = 0; symbol->iterate_reference (i, ref); i++)
     {
-      symtab_node *node = symtab_alias_ultimate_target (ref->referred, NULL);
+      symtab_node *node = ref->referred->ultimate_alias_target ();
+
+      /* Always keep thunks in same sections as target function.  */
+      if (is_a <cgraph_node *>(node))
+       node = dyn_cast <cgraph_node *> (node)->function_symbol ();
       if (!node->aux && node->definition)
        {
           node->aux = *first;
@@ -182,8 +190,11 @@ enqueue_references (symtab_node **first,
          enqueue_references (first, edge->callee);
        else
          {
-           symtab_node *node = symtab_alias_ultimate_target (edge->callee,
-                                                             NULL);
+           symtab_node *node = edge->callee->ultimate_alias_target ();
+
+           /* Always keep thunks in same sections as target function.  */
+           if (is_a <cgraph_node *>(node))
+             node = dyn_cast <cgraph_node *> (node)->function_symbol ();
            if (!node->aux && node->definition)
              {
                 node->aux = *first;
@@ -194,7 +205,7 @@ enqueue_references (symtab_node **first,
 }
 
 /* Set comdat group of SYMBOL to GROUP.
-   Callback for symtab_for_node_and_aliases.  */
+   Callback for for_node_and_aliases.  */
 
 bool
 set_comdat_group (symtab_node *symbol,
@@ -204,17 +215,27 @@ set_comdat_group (symtab_node *symbol,
 
   gcc_assert (!symbol->get_comdat_group ());
   symbol->set_comdat_group (head->get_comdat_group ());
-  symtab_add_to_same_comdat_group (symbol, head);
+  symbol->add_to_same_comdat_group (head);
   return false;
 }
 
+/* Set comdat group of SYMBOL to GROUP.
+   Callback for for_node_thunks_and_aliases.  */
+
+bool
+set_comdat_group_1 (cgraph_node *symbol,
+                   void *head_p)
+{
+  return set_comdat_group (symbol, head_p);
+}
+
 /* The actual pass with the main dataflow loop.  */
 
 static unsigned int
 ipa_comdats (void)
 {
-  pointer_map<tree> map;
-  pointer_map<symtab_node *> comdat_head_map;
+  hash_map<symtab_node *, tree> map (251);
+  hash_map<tree, symtab_node *> comdat_head_map (251);
   symtab_node *symbol;
   bool comdat_group_seen = false;
   symtab_node *first = (symtab_node *) (void *) 1;
@@ -225,12 +246,12 @@ ipa_comdats (void)
      ERROR_MARK_NODE as bottom for the propagation.  */
 
   FOR_EACH_DEFINED_SYMBOL (symbol)
-    if (!symtab_real_symbol_p (symbol))
+    if (!symbol->real_symbol_p ())
       ;
     else if ((group = symbol->get_comdat_group ()) != NULL)
       {
-        *map.insert (symbol) = group;
-        *comdat_head_map.insert (group) = symbol;
+        map.put (symbol, group);
+        comdat_head_map.put (group, symbol);
        comdat_group_seen = true;
 
        /* Mark the symbol so we won't waste time visiting it for dataflow.  */
@@ -248,7 +269,12 @@ ipa_comdats (void)
                 && (DECL_STATIC_CONSTRUCTOR (symbol->decl)
                     || DECL_STATIC_DESTRUCTOR (symbol->decl))))
       {
-       *map.insert (symtab_alias_ultimate_target (symbol, NULL)) = error_mark_node;
+       symtab_node *target = symbol->ultimate_alias_target ();
+
+       /* Always keep thunks in same sections as target function.  */
+       if (is_a <cgraph_node *>(target))
+         target = dyn_cast <cgraph_node *> (target)->function_symbol ();
+       map.put (target, error_mark_node);
 
        /* Mark the symbol so we won't waste time visiting it for dataflow.  */
        symbol->aux = (symtab_node *) (void *) 1;
@@ -278,7 +304,7 @@ ipa_comdats (void)
       first = (symtab_node *)first->aux;
 
       /* Get current lattice value of SYMBOL.  */
-      val = map.contains (symbol);
+      val = map.get (symbol);
       if (val)
        group = *val;
 
@@ -301,7 +327,7 @@ ipa_comdats (void)
       if (val)
        *val = newgroup;
       else
-       *map.insert (symbol) = newgroup;
+       map.put (symbol, newgroup);
       enqueue_references (&first, symbol);
 
       /* We may need to revisit the symbol unless it is BOTTOM.  */
@@ -313,23 +339,41 @@ ipa_comdats (void)
 
   FOR_EACH_DEFINED_SYMBOL (symbol)
     {
+      struct cgraph_node *fun;
       symbol->aux = NULL; 
       if (!symbol->get_comdat_group ()
          && !symbol->alias
-         && symtab_real_symbol_p (symbol))
+         && (!(fun = dyn_cast <cgraph_node *> (symbol))
+             || !fun->thunk.thunk_p)
+         && symbol->real_symbol_p ())
        {
-         tree group = *map.contains (symbol);
+         tree *val = map.get (symbol);
+
+         /* A NULL here means that SYMBOL is unreachable in the definition
+            of ipa-comdats. Either ipa-comdats is wrong about this or someone
+            forgot to cleanup and remove unreachable functions earlier.  */
+         gcc_assert (val);
+
+         tree group = *val;
 
          if (group == error_mark_node)
            continue;
          if (dump_file)
            {
              fprintf (dump_file, "Localizing symbol\n");
-             dump_symtab_node (dump_file, symbol);
+             symbol->dump (dump_file);
              fprintf (dump_file, "To group: %s\n", IDENTIFIER_POINTER (group));
            }
-         symtab_for_node_and_aliases (symbol, set_comdat_group,
-                                      *comdat_head_map.contains (group), true);
+         if (is_a <cgraph_node *> (symbol))
+          dyn_cast <cgraph_node *>(symbol)->call_for_symbol_thunks_and_aliases
+                 (set_comdat_group_1,
+                  *comdat_head_map.get (group),
+                  true);
+         else
+          symbol->call_for_symbol_and_aliases
+                 (set_comdat_group,
+                  *comdat_head_map.get (group),
+                  true);
        }
     }
   return 0;
@@ -342,7 +386,6 @@ const pass_data pass_data_ipa_comdats =
   IPA_PASS, /* type */
   "comdats", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  true, /* has_execute */
   TV_IPA_COMDATS, /* tv_id */
   0, /* properties_required */
   0, /* properties_provided */