]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
symtab.c (symtab_node::reset_section): New method.
authorJan Hubicka <hubicka@ucw.cz>
Thu, 12 Jun 2014 22:23:55 +0000 (00:23 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 12 Jun 2014 22:23:55 +0000 (22:23 +0000)
* symtab.c (symtab_node::reset_section): New method.
* cgraph.c (cgraph_node_cannot_be_local_p_1): Accept non-local
for localization.
* cgraph.h (reset_section): Declare.
* ipa-inline-analysis.c (do_estimate_growth): Check for comdat groups;
do not consider comdat locals.
* cgraphclones.c (set_new_clone_decl_and_node_flags): Get section
for new symbol.
* ipa-visiblity.c (cgraph_externally_visible_p): Cleanup.
(update_visibility_by_resolution_info): Consider UNDEF; fix checking;
reset sections of symbols dragged out of the comdats.
(function_and_variable_visibility): Reset sections of localized symbols.

From-SVN: r211600

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphclones.c
gcc/ipa-inline-analysis.c
gcc/ipa-visibility.c
gcc/symtab.c

index a8dcd62fd3da9e28626c4e12d9dd7ab4866e8fb9..f3deff30f5200d11730feaadd02cdf4ffb9b47be 100644 (file)
@@ -1,3 +1,18 @@
+2014-06-12  Jan Hubicka  <hubicka@ucw.cz>
+
+       * symtab.c (symtab_node::reset_section): New method.
+       * cgraph.c (cgraph_node_cannot_be_local_p_1): Accept non-local
+       for localization.
+       * cgraph.h (reset_section): Declare.
+       * ipa-inline-analysis.c (do_estimate_growth): Check for comdat groups;
+       do not consider comdat locals.
+       * cgraphclones.c (set_new_clone_decl_and_node_flags): Get section
+       for new symbol.
+       * ipa-visiblity.c (cgraph_externally_visible_p): Cleanup.
+       (update_visibility_by_resolution_info): Consider UNDEF; fix checking;
+       reset sections of symbols dragged out of the comdats.
+       (function_and_variable_visibility): Reset sections of localized symbols.
+
 2014-06-12  Jan Hubicka  <hubicka@ucw.cz>
 
        * tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Reorg
index 610bf6717c153e35de26cf21d4cd286023785d8d..f535740f11070ea33667223906c9ff31e1a51de0 100644 (file)
@@ -2169,6 +2169,7 @@ cgraph_node_cannot_be_local_p_1 (struct cgraph_node *node,
                && !node->forced_by_abi
                && !symtab_used_from_object_file_p (node)
                && !node->same_comdat_group)
+              || DECL_EXTERNAL (node->decl)
               || !node->externally_visible));
 }
 
@@ -2259,14 +2260,14 @@ cgraph_make_node_local_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
     {
       symtab_make_decl_local (node->decl);
 
-      node->set_section (NULL);
       node->set_comdat_group (NULL);
       node->externally_visible = false;
       node->forced_by_abi = false;
       node->local.local = true;
-      node->set_section (NULL);
+      node->reset_section ();
       node->unique_name = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
-                                 || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
+                          || node->unique_name
+                          || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
       node->resolution = LDPR_PREVAILING_DEF_IRONLY;
       gcc_assert (cgraph_function_body_availability (node) == AVAIL_LOCAL);
     }
index 1a5e85e2a6acb8e03ef819cf85543221d73dbcf4..ce99166fd4d718c9a52dda9ebce36b0c0e667cc4 100644 (file)
@@ -208,6 +208,7 @@ public:
   /* Set section for symbol and its aliases.  */
   void set_section (const char *section);
   void set_section_for_node (const char *section);
+  void reset_section ();
 };
 
 enum availability
index 6f83d74605877839d98adfae8abd170cae2c7282..94c9760b37f0053b6208f9e77e9e8b00ad0e4edc 100644 (file)
@@ -293,6 +293,7 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node)
   new_node->externally_visible = 0;
   new_node->local.local = 1;
   new_node->lowered = true;
+  new_node->reset_section ();
 }
 
 /* Duplicate thunk THUNK if necessary but make it to refer to NODE.
index c50a7227500c693b273a6c7499419ff5e6bcbd34..7f9febc5fe80e7b8612f8e0765d6204d186dbae1 100644 (file)
@@ -3877,7 +3877,7 @@ do_estimate_growth (struct cgraph_node *node)
       /* COMDAT functions are very often not shared across multiple units
          since they come from various template instantiations.
          Take this into account.  */
-      else if (DECL_COMDAT (node->decl)
+      else if (node->externally_visible && node->get_comdat_group ()
               && cgraph_can_remove_if_no_direct_calls_p (node))
        d.growth -= (info->size
                     * (100 - PARAM_VALUE (PARAM_COMDAT_SHARING_PROBABILITY))
@@ -3928,7 +3928,7 @@ growth_likely_positive (struct cgraph_node *node, int edge_growth ATTRIBUTE_UNUS
       && (ret = node_growth_cache[node->uid]))
     return ret > 0;
   if (!cgraph_will_be_removed_from_program_if_no_direct_calls (node)
-      && (!DECL_COMDAT (node->decl)
+      && (!node->externally_visible || !node->get_comdat_group ()
          || !cgraph_can_remove_if_no_direct_calls_p (node)))
     return true;
   max_callers = inline_summary (node)->size * 4 / edge_growth + 2;
index 4e0fd9e0b405056a38723e6883a0465566f27c19..97f9a00e36d10454bbb84c2f18af24a388cc1025 100644 (file)
@@ -236,7 +236,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
     return true;
   if (node->resolution == LDPR_PREVAILING_DEF_IRONLY)
     return false;
-  /* When doing LTO or whole program, we can bring COMDAT functoins static.
+  /* When doing LTO or whole program, we can bring COMDAT functions static.
      This improves code quality and we know we will duplicate them at most twice
      (in the case that we are not using plugin and link with object file
       implementing same COMDAT)  */
@@ -295,8 +295,6 @@ varpool_externally_visible_p (varpool_node *vnode)
      Even if the linker clams the symbol is unused, never bring internal
      symbols that are declared by user as used or externally visible.
      This is needed for i.e. references from asm statements.   */
-  if (symtab_used_from_object_file_p (vnode))
-    return true;
   if (vnode->resolution == LDPR_PREVAILING_DEF_IRONLY)
     return false;
 
@@ -386,7 +384,8 @@ update_visibility_by_resolution_info (symtab_node * node)
 
   if (!node->externally_visible
       || (!DECL_WEAK (node->decl) && !DECL_ONE_ONLY (node->decl))
-      || node->resolution == LDPR_UNKNOWN)
+      || node->resolution == LDPR_UNKNOWN
+      || node->resolution == LDPR_UNDEF)
     return;
 
   define = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
@@ -397,7 +396,7 @@ update_visibility_by_resolution_info (symtab_node * node)
   if (node->same_comdat_group)
     for (symtab_node *next = node->same_comdat_group;
         next != node; next = next->same_comdat_group)
-      gcc_assert (!node->externally_visible
+      gcc_assert (!next->externally_visible
                  || define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY
                                || next->resolution == LDPR_PREVAILING_DEF
                                || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP));
@@ -411,11 +410,15 @@ update_visibility_by_resolution_info (symtab_node * node)
        if (next->externally_visible
            && !define)
          DECL_EXTERNAL (next->decl) = true;
+       if (!next->alias)
+         next->reset_section ();
       }
   node->set_comdat_group (NULL);
   DECL_WEAK (node->decl) = false;
   if (!define)
     DECL_EXTERNAL (node->decl) = true;
+  if (!node->alias)
+    node->reset_section ();
   symtab_dissolve_same_comdat_group_list (node);
 }
 
@@ -476,7 +479,7 @@ function_and_variable_visibility (bool whole_program)
          symtab_dissolve_same_comdat_group_list (node);
        }
       gcc_assert ((!DECL_WEAK (node->decl)
-                 && !DECL_COMDAT (node->decl))
+                  && !DECL_COMDAT (node->decl))
                  || TREE_PUBLIC (node->decl)
                  || node->weakref
                  || DECL_EXTERNAL (node->decl));
@@ -494,6 +497,7 @@ function_and_variable_visibility (bool whole_program)
          && node->definition && !node->weakref
          && !DECL_EXTERNAL (node->decl))
        {
+         bool reset = TREE_PUBLIC (node->decl);
          gcc_assert (whole_program || in_lto_p
                      || !TREE_PUBLIC (node->decl));
          node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
@@ -512,9 +516,9 @@ function_and_variable_visibility (bool whole_program)
                     next = next->same_comdat_group)
                {
                  next->set_comdat_group (NULL);
-                 if (!next->alias)
-                   next->set_section (NULL);
                  symtab_make_decl_local (next->decl);
+                 if (!node->alias)
+                   node->reset_section ();
                  next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
                                        || next->unique_name
                                        || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
@@ -528,9 +532,9 @@ function_and_variable_visibility (bool whole_program)
            }
          if (TREE_PUBLIC (node->decl))
            node->set_comdat_group (NULL);
-         if (DECL_COMDAT (node->decl) && !node->alias)
-           node->set_section (NULL);
          symtab_make_decl_local (node->decl);
+         if (reset && !node->alias)
+           node->reset_section ();
        }
 
       if (node->thunk.thunk_p
@@ -632,6 +636,7 @@ function_and_variable_visibility (bool whole_program)
       if (!vnode->externally_visible
          && !vnode->weakref)
        {
+         bool reset = TREE_PUBLIC (vnode->decl);
          gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->decl));
          vnode->unique_name = ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY
                                       || vnode->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
@@ -647,9 +652,9 @@ function_and_variable_visibility (bool whole_program)
                     next = next->same_comdat_group)
                {
                  next->set_comdat_group (NULL);
-                 if (!next->alias)
-                   next->set_section (NULL);
                  symtab_make_decl_local (next->decl);
+                 if (!next->alias)
+                   next->reset_section ();
                  next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
                                        || next->unique_name
                                        || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
@@ -659,9 +664,9 @@ function_and_variable_visibility (bool whole_program)
            }
          if (TREE_PUBLIC (vnode->decl))
            vnode->set_comdat_group (NULL);
-         if (DECL_COMDAT (vnode->decl) && !vnode->alias)
-           vnode->set_section (NULL);
          symtab_make_decl_local (vnode->decl);
+         if (reset && !vnode->alias)
+           vnode->reset_section ();
          vnode->resolution = LDPR_PREVAILING_DEF_IRONLY;
        }
       update_visibility_by_resolution_info (vnode);
index 8158acc5bda8acb9d04e7acf52bd0ee771ad7279..b68a16fcde83b094d61a5d8cf041a435a7e08e8a 100644 (file)
@@ -1176,6 +1176,21 @@ symtab_node::set_section (const char *section)
   symtab_for_node_and_aliases (this, set_section_1, const_cast<char *>(section), true);
 }
 
+/* Reset section of NODE.  That is when NODE is being brought local
+   we may want to clear section produced for comdat group and depending
+   on function-sections produce now, local, unique section for it.  */
+
+void
+symtab_node::reset_section ()
+{
+  if (!this->implicit_section)
+    return;
+  this->set_section (NULL);
+  resolve_unique_section (this->decl, 0,
+                         is_a <cgraph_node *> (this)
+                         ? flag_function_sections : flag_data_sections);
+}
+
 /* Worker for symtab_resolve_alias.  */
 
 static bool