summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-12 22:23:55 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-12 22:23:55 +0000
commit922f76a868d0451dcb7227dc2a4fe7a1bb28bf61 (patch)
tree614d47109aba7fe36bcb27ee602307278455a372 /gcc
parent454eae94e46e60b29dd6b6e97c911294527e972e (diff)
downloadgcc-922f76a868d0451dcb7227dc2a4fe7a1bb28bf61.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@211600 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/cgraph.c7
-rw-r--r--gcc/cgraph.h1
-rw-r--r--gcc/cgraphclones.c1
-rw-r--r--gcc/ipa-inline-analysis.c4
-rw-r--r--gcc/ipa-visibility.c33
-rw-r--r--gcc/symtab.c15
7 files changed, 57 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a8dcd62fd3d..f3deff30f52 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,20 @@
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
to use symtab and decl_binds_to_current_def_p
* tree-vectorizer.c (increase_alignment): Increase alignment
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 610bf6717c1..f535740f110 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -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);
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 1a5e85e2a6a..ce99166fd4d 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 6f83d746058..94c9760b37f 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -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.
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index c50a7227500..7f9febc5fe8 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -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;
diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c
index 4e0fd9e0b40..97f9a00e36d 100644
--- a/gcc/ipa-visibility.c
+++ b/gcc/ipa-visibility.c
@@ -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);
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 8158acc5bda..b68a16fcde8 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -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