aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-05-18 21:16:08 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-05-18 21:16:08 +0000
commit17354446b8fcc42b5b02e3099c6ae282ca8763f0 (patch)
treeaee22104f1c906424fa7c6d5419c00c6dde1ea0c
parentb166c4752e3200c6f86fab5244eca1f18434041d (diff)
* ipa.c (update_visibility_by_resolution_info): New function.
(function_and_variable_visibility): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210592 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/ipa.c78
2 files changed, 51 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 18ab7bd0d67..56bf5ce2ffc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2014-05-17 Jan Hubicka <hubicka@ucw.cz>
+ * ipa.c (update_visibility_by_resolution_info): New function.
+ (function_and_variable_visibility): Use it.
+
+2014-05-17 Jan Hubicka <hubicka@ucw.cz>
+
* cgraph.h (symtab_first_defined_symbol, symtab_next_defined_symbol):
New functions.
(FOR_EACH_DEFINED_SYMBOL): New macro.
diff --git a/gcc/ipa.c b/gcc/ipa.c
index da424914ce9..ef544615a4a 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -978,6 +978,50 @@ can_replace_by_local_alias (symtab_node *node)
&& !symtab_can_be_discarded (node));
}
+/* In LTO we can remove COMDAT groups and weak symbols.
+ Either turn them into normal symbols or external symbol depending on
+ resolution info. */
+
+static void
+update_visibility_by_resolution_info (symtab_node * node)
+{
+ bool define;
+
+ if (!node->externally_visible
+ || (!DECL_WEAK (node->decl) && !DECL_ONE_ONLY (node->decl))
+ || node->resolution == LDPR_UNKNOWN)
+ return;
+
+ define = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
+ || node->resolution == LDPR_PREVAILING_DEF
+ || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
+
+ /* The linker decisions ought to agree in the whole group. */
+ 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
+ || define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY
+ || next->resolution == LDPR_PREVAILING_DEF
+ || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP));
+
+ if (node->same_comdat_group)
+ for (symtab_node *next = node->same_comdat_group;
+ next != node; next = next->same_comdat_group)
+ {
+ DECL_COMDAT_GROUP (next->decl) = NULL;
+ DECL_WEAK (next->decl) = false;
+ if (next->externally_visible
+ && !define)
+ DECL_EXTERNAL (next->decl) = true;
+ }
+ DECL_COMDAT_GROUP (node->decl) = NULL;
+ DECL_WEAK (node->decl) = false;
+ if (!define)
+ DECL_EXTERNAL (node->decl) = true;
+ symtab_dissolve_same_comdat_group_list (node);
+}
+
/* Mark visibility of all functions.
A local function is one whose calls can occur only in the current
@@ -1116,38 +1160,7 @@ function_and_variable_visibility (bool whole_program)
DECL_EXTERNAL (node->decl) = 1;
}
- /* If whole comdat group is used only within LTO code, we can dissolve it,
- we handle the unification ourselves.
- We keep COMDAT and weak so visibility out of DSO does not change.
- Later we may bring the symbols static if they are not exported. */
- if (DECL_ONE_ONLY (node->decl)
- && (node->resolution == LDPR_PREVAILING_DEF_IRONLY
- || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP))
- {
- symtab_node *next = node;
-
- if (node->same_comdat_group)
- for (next = node->same_comdat_group;
- next != node;
- next = next->same_comdat_group)
- if (next->externally_visible
- && (next->resolution != LDPR_PREVAILING_DEF_IRONLY
- && next->resolution != LDPR_PREVAILING_DEF_IRONLY_EXP))
- break;
- if (node == next)
- {
- if (node->same_comdat_group)
- for (next = node->same_comdat_group;
- next != node;
- next = next->same_comdat_group)
- {
- DECL_COMDAT_GROUP (next->decl) = NULL;
- DECL_WEAK (next->decl) = false;
- }
- DECL_COMDAT_GROUP (node->decl) = NULL;
- symtab_dissolve_same_comdat_group_list (node);
- }
- }
+ update_visibility_by_resolution_info (node);
}
FOR_EACH_DEFINED_FUNCTION (node)
{
@@ -1234,6 +1247,7 @@ function_and_variable_visibility (bool whole_program)
symtab_dissolve_same_comdat_group_list (vnode);
vnode->resolution = LDPR_PREVAILING_DEF_IRONLY;
}
+ update_visibility_by_resolution_info (vnode);
}
if (dump_file)