aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraph.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r--gcc/cgraph.c78
1 files changed, 68 insertions, 10 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index fff437a..66a88db 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -97,6 +97,7 @@ The callgraph:
#include "diagnostic-core.h"
#include "rtl.h"
#include "ipa-utils.h"
+#include "lto-streamer.h"
static void cgraph_node_remove_callers (struct cgraph_node *node);
static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
@@ -1975,20 +1976,43 @@ debug_cgraph (void)
void
change_decl_assembler_name (tree decl, tree name)
{
- gcc_assert (!assembler_name_hash);
+ struct cgraph_node *node;
+ void **slot;
if (!DECL_ASSEMBLER_NAME_SET_P (decl))
+ SET_DECL_ASSEMBLER_NAME (decl, name);
+ else
{
- SET_DECL_ASSEMBLER_NAME (decl, name);
- return;
- }
- if (name == DECL_ASSEMBLER_NAME (decl))
- return;
+ if (name == DECL_ASSEMBLER_NAME (decl))
+ return;
- if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
- && DECL_RTL_SET_P (decl))
- warning (0, "%D renamed after being referenced in assembly", decl);
+ if (assembler_name_hash
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && (node = cgraph_get_node_or_alias (decl)) != NULL)
+ {
+ tree old_name = DECL_ASSEMBLER_NAME (decl);
+ slot = htab_find_slot_with_hash (assembler_name_hash, old_name,
+ decl_assembler_name_hash (old_name),
+ NO_INSERT);
+ /* Inline clones are not hashed. */
+ if (slot && *slot == node)
+ htab_clear_slot (assembler_name_hash, slot);
+ }
+ if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
+ && DECL_RTL_SET_P (decl))
+ warning (0, "%D renamed after being referenced in assembly", decl);
- SET_DECL_ASSEMBLER_NAME (decl, name);
+ SET_DECL_ASSEMBLER_NAME (decl, name);
+ }
+ if (assembler_name_hash
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && (node = cgraph_get_node_or_alias (decl)) != NULL)
+ {
+ slot = htab_find_slot_with_hash (assembler_name_hash, name,
+ decl_assembler_name_hash (name),
+ INSERT);
+ gcc_assert (!*slot);
+ *slot = node;
+ }
}
/* Add a top-level asm statement to the list. */
@@ -2459,6 +2483,40 @@ cgraph_make_decl_local (tree decl)
if (DECL_COMDAT (decl))
{
+ /* It is possible that we are linking against library defining same COMDAT
+ function. To avoid conflict we need to rename our local name of the
+ function just in the case WHOPR partitioning decide to make it hidden
+ to avoid cross partition references. */
+ if (flag_wpa)
+ {
+ const char *old_name;
+
+ old_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ struct cgraph_node *node = cgraph_get_node_or_alias (decl);
+ change_decl_assembler_name (decl,
+ clone_function_name (decl, "local"));
+ if (node->local.lto_file_data)
+ lto_record_renamed_decl (node->local.lto_file_data,
+ old_name,
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (decl)));
+ }
+ else if (TREE_CODE (decl) == VAR_DECL)
+ {
+ struct varpool_node *vnode = varpool_get_node (decl);
+ /* change_decl_assembler_name will warn here on vtables because
+ C++ frontend still sets TREE_SYMBOL_REFERENCED on them. */
+ SET_DECL_ASSEMBLER_NAME (decl,
+ clone_function_name (decl, "local"));
+ if (vnode->lto_file_data)
+ lto_record_renamed_decl (vnode->lto_file_data,
+ old_name,
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (decl)));
+ }
+ }
DECL_SECTION_NAME (decl) = 0;
DECL_COMDAT (decl) = 0;
}