cgraph.h (clone_function_name_1): Declare.
authorBernd Schmidt <bernds@codesourcery.com>
Fri, 20 Feb 2015 12:55:37 +0000 (12:55 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Fri, 20 Feb 2015 12:55:37 +0000 (12:55 +0000)
     * cgraph.h (clone_function_name_1): Declare.
     * cgraphclones.c (clone_function_name_1): New function.
     (clone_function_name): Use it.
     * lto-partition.c: Include "stringpool.h".
     (must_not_rename, maybe_rewrite_identifier,
     validize_symbol_for_target): New static functions.
     (privatize_symbol_name): Use must_not_rename.
     (promote_symbol): Call validize_symbol_for_target.
     (lto_promote_cross_file_statics): Likewise.
     (lto_promote_statics_nonwpa): Likewise.

From-SVN: r220855

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphclones.c
gcc/lto/lto-partition.c

index 8d37e3534e7a2ba1dabf08b971cbce6f97c3c493..a899997e8eb97d850da0ba98d1f126fe98814dc1 100644 (file)
@@ -1,3 +1,16 @@
+2015-02-20  Bernd Schmidt  <bernds@codesourcery.com>
+
+       * cgraph.h (clone_function_name_1): Declare.
+       * cgraphclones.c (clone_function_name_1): New function.
+       (clone_function_name): Use it.
+       * lto-partition.c: Include "stringpool.h".
+       (must_not_rename, maybe_rewrite_identifier,
+       validize_symbol_for_target): New static functions.
+       (privatize_symbol_name): Use must_not_rename.
+       (promote_symbol): Call validize_symbol_for_target.
+       (lto_promote_cross_file_statics): Likewise.
+       (lto_promote_statics_nonwpa): Likewise.
+
 2015-02-20  Georg-Johann Lay  <avr@gjlay.de>
 
        PR target/64452
index 06d270458b00db76788a4b4e15d81e0733839530..ec3cccda866eb31dbc95f072850f431b068fc299 100644 (file)
@@ -2206,6 +2206,7 @@ basic_block init_lowered_empty_function (tree, bool, gcov_type);
 
 /* In cgraphclones.c  */
 
+tree clone_function_name_1 (const char *, const char *);
 tree clone_function_name (tree decl, const char *);
 
 void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
index 655b0ab7804862f0a3759cab2b8f7a59d1c21f19..d0a5f707136e247c26cd0b63a04d3c473fd3aea1 100644 (file)
@@ -533,19 +533,19 @@ cgraph_node::create_clone (tree decl, gcov_type gcov_count, int freq,
   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] = '.';
@@ -558,6 +558,16 @@ clone_function_name (tree decl, const char *suffix)
   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.
 
index c1179cb2eff9d3d73dcf22b97e536ad1ec1a431a..235b735a8fdb2c1b3cf527ad2d9f176ee5658cb0 100644 (file)
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-inline.h"
 #include "ipa-utils.h"
 #include "lto-partition.h"
+#include "stringpool.h"
 
 vec<ltrans_partition> ltrans_partitions;
 
@@ -783,29 +784,12 @@ lto_balanced_map (int n_lto_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
@@ -813,9 +797,9 @@ privatize_symbol_name (symtab_node *node)
     {
       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,
@@ -825,12 +809,103 @@ privatize_symbol_name (symtab_node *node)
     {
       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
@@ -868,7 +943,10 @@ promote_symbol (symtab_node *node)
   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));
@@ -1007,7 +1085,10 @@ lto_promote_cross_file_statics (void)
              /* ... 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);
         }
@@ -1022,5 +1103,8 @@ lto_promote_statics_nonwpa (void)
 {
   symtab_node *node;
   FOR_EACH_SYMBOL (node)
-    rename_statics (NULL, node);
+    {
+      rename_statics (NULL, node);
+      validize_symbol_for_target (node);
+    }
 }