return new_node;
}
-/* Return a new assembler name for a clone of DECL with SUFFIX. */
-
static GTY(()) unsigned int clone_fn_id_num;
+/* Return a new assembler name for a clone with SUFFIX of a decl named
+ NAME. */
+
tree
-clone_function_name (tree decl, const char *suffix)
+clone_function_name_1 (const char *name, const char *suffix)
{
- tree name = DECL_ASSEMBLER_NAME (decl);
- size_t len = IDENTIFIER_LENGTH (name);
+ size_t len = strlen (name);
char *tmp_name, *prefix;
prefix = XALLOCAVEC (char, len + strlen (suffix) + 2);
- memcpy (prefix, IDENTIFIER_POINTER (name), len);
+ memcpy (prefix, name, len);
strcpy (prefix + len + 1, suffix);
#ifndef NO_DOT_IN_LABEL
prefix[len] = '.';
return get_identifier (tmp_name);
}
+/* Return a new assembler name for a clone of DECL with SUFFIX. */
+
+tree
+clone_function_name (tree decl, const char *suffix)
+{
+ tree name = DECL_ASSEMBLER_NAME (decl);
+ return clone_function_name_1 (IDENTIFIER_POINTER (name), suffix);
+}
+
+
/* Create callgraph node clone with new declaration. The actual body will
be copied later at compilation stage.
#include "ipa-inline.h"
#include "ipa-utils.h"
#include "lto-partition.h"
+#include "stringpool.h"
vec<ltrans_partition> ltrans_partitions;
free (order);
}
-/* Mangle NODE symbol name into a local name.
- This is necessary to do
- 1) if two or more static vars of same assembler name
- are merged into single ltrans unit.
- 2) if prevoiusly static var was promoted hidden to avoid possible conflict
- with symbols defined out of the LTO world.
-*/
+/* Return true if we must not change the name of the NODE. The name as
+ extracted from the corresponding decl should be passed in NAME. */
static bool
-privatize_symbol_name (symtab_node *node)
+must_not_rename (symtab_node *node, const char *name)
{
- tree decl = node->decl;
- cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
- const char *name;
-
- /* If we want to privatize instrumentation clone
- then we need to change original function name
- which is used via transparent alias chain. */
- if (cnode && cnode->instrumentation_clone)
- decl = cnode->orig_decl;
-
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
/* Our renaming machinery do not handle more than one change of assembler name.
We should not need more than one anyway. */
if (node->lto_file_data
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
- "Not privatizing symbol name: %s. It privatized already.\n",
- name);
- return false;
+ "Not privatizing symbol name: %s. It privatized already.\n",
+ name);
+ return true;
}
/* Avoid mangling of already mangled clones.
??? should have a flag whether a symbol has a 'private' name already,
{
if (symtab->dump_file)
fprintf (symtab->dump_file,
- "Not privatizing symbol name: %s. Has unique name.\n",
- name);
- return false;
+ "Not privatizing symbol name: %s. Has unique name.\n",
+ name);
+ return true;
}
+ return false;
+}
+
+/* If we are an offload compiler, we may have to rewrite symbols to be
+ valid on this target. Return either PTR or a modified version of it. */
+
+static const char *
+maybe_rewrite_identifier (const char *ptr)
+{
+#if defined ACCEL_COMPILER && (defined NO_DOT_IN_LABEL || defined NO_DOLLAR_IN_LABEL)
+#ifndef NO_DOT_IN_LABEL
+ char valid = '.';
+ const char reject[] = "$";
+#elif !defined NO_DOLLAR_IN_LABEL
+ char valid = '$';
+ const char reject[] = ".";
+#else
+ char valid = '_';
+ const char reject[] = ".$";
+#endif
+
+ char *copy = NULL;
+ const char *match = ptr;
+ for (;;)
+ {
+ size_t off = strcspn (match, reject);
+ if (match[off] == '\0')
+ break;
+ if (copy == NULL)
+ {
+ copy = xstrdup (ptr);
+ match = copy;
+ }
+ copy[off] = valid;
+ }
+ return match;
+#else
+ return ptr;
+#endif
+}
+
+/* Ensure that the symbol in NODE is valid for the target, and if not,
+ rewrite it. */
+
+static void
+validize_symbol_for_target (symtab_node *node)
+{
+ tree decl = node->decl;
+ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+ if (must_not_rename (node, name))
+ return;
+
+ const char *name2 = maybe_rewrite_identifier (name);
+ if (name2 != name)
+ {
+ symtab->change_decl_assembler_name (decl, get_identifier (name2));
+ if (node->lto_file_data)
+ lto_record_renamed_decl (node->lto_file_data, name,
+ IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (decl)));
+ }
+}
+
+/* Mangle NODE symbol name into a local name.
+ This is necessary to do
+ 1) if two or more static vars of same assembler name
+ are merged into single ltrans unit.
+ 2) if previously static var was promoted hidden to avoid possible conflict
+ with symbols defined out of the LTO world. */
+
+static bool
+privatize_symbol_name (symtab_node *node)
+{
+ tree decl = node->decl;
+ const char *name;
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+
+ /* If we want to privatize instrumentation clone
+ then we need to change original function name
+ which is used via transparent alias chain. */
+ if (cnode && cnode->instrumentation_clone)
+ decl = cnode->orig_decl;
+
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+ if (must_not_rename (node, name))
+ return false;
+
+ name = maybe_rewrite_identifier (name);
symtab->change_decl_assembler_name (decl,
- clone_function_name (decl, "lto_priv"));
+ clone_function_name_1 (name,
+ "lto_priv"));
if (node->lto_file_data)
lto_record_renamed_decl (node->lto_file_data, name,
IDENTIFIER_POINTER
if (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
&& DECL_VISIBILITY_SPECIFIED (node->decl)
&& TREE_PUBLIC (node->decl))
- return;
+ {
+ validize_symbol_for_target (node);
+ return;
+ }
gcc_checking_assert (!TREE_PUBLIC (node->decl)
&& !DECL_EXTERNAL (node->decl));
/* ... or if we do not partition it. This mean that it will
appear in every partition refernecing it. */
|| node->get_partitioning_class () != SYMBOL_PARTITION)
- continue;
+ {
+ validize_symbol_for_target (node);
+ continue;
+ }
promote_symbol (node);
}
{
symtab_node *node;
FOR_EACH_SYMBOL (node)
- rename_statics (NULL, node);
+ {
+ rename_statics (NULL, node);
+ validize_symbol_for_target (node);
+ }
}