diff mbox

nvptx backend: fix and streamline symbol renaming

Message ID 1459423116-11313-1-git-send-email-amonakov@ispras.ru
State New
Headers show

Commit Message

Alexander Monakov March 31, 2016, 11:18 a.m. UTC
This fixes a bug in the NVPTX backend where taking the address of a function
renamed by the backend (e.g. 'call' or 'malloc') would wrongly use the
original name. Now all decl renaming is handled up front via
TARGET_MANGLE_DECL_ASSEMBLER_NAME hook, which becomes the only caller of
nvptx_name_replacement.

En passant, it also fixes one instance where handling of star prefix on
user-supplied DECL_ASSEMBLER_NAME was missing.

gcc/
	* config/nvptx/nvptx.c (nvptx_name_replacement): Return NULL if no
	replacement needed.
	(nvptx_mangle_decl_assembler_name): New.
	(write_fn_proto): Do not call nvptx_name_replacement.
	(write_fn_proto_from_insn): Ditto.
	(nvptx_output_call_insn): Ditto.
	(TARGET_MANGLE_DECL_ASSEMBLER_NAME): Define.

gcc/testsuite/
	* gcc.target/nvptx/rename-call.c: New test.
	* gcc.target/nvptx/rename-call-2.c: New test.
	* gcc.target/nvptx/asm-name.c: New test.
---
Hello,

This is an NVPTX bug fix that I'm going to apply to gomp-nvptx branch, but
it's a generally useful fix. OK for trunk? Now or when stage1 opens?

Thanks.
Alexander


 gcc/config/nvptx/nvptx.c                       | 26 ++++++++++++++++----------
 gcc/testsuite/gcc.target/nvptx/asm-name.c      | 14 ++++++++++++++
 gcc/testsuite/gcc.target/nvptx/rename-call-2.c | 12 ++++++++++++
 gcc/testsuite/gcc.target/nvptx/rename-call.c   | 16 ++++++++++++++++
 4 files changed, 58 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/nvptx/asm-name.c
 create mode 100644 gcc/testsuite/gcc.target/nvptx/rename-call-2.c
 create mode 100644 gcc/testsuite/gcc.target/nvptx/rename-call.c

Comments

Nathan Sidwell March 31, 2016, 12:09 p.m. UTC | #1
On 03/31/16 07:18, Alexander Monakov wrote:
> This fixes a bug in the NVPTX backend where taking the address of a function
> renamed by the backend (e.g. 'call' or 'malloc') would wrongly use the
> original name. Now all decl renaming is handled up front via
> TARGET_MANGLE_DECL_ASSEMBLER_NAME hook, which becomes the only caller of
> nvptx_name_replacement.
>
> En passant, it also fixes one instance where handling of star prefix on
> user-supplied DECL_ASSEMBLER_NAME was missing.
>
> gcc/
> 	* config/nvptx/nvptx.c (nvptx_name_replacement): Return NULL if no
> 	replacement needed.
> 	(nvptx_mangle_decl_assembler_name): New.
> 	(write_fn_proto): Do not call nvptx_name_replacement.
> 	(write_fn_proto_from_insn): Ditto.
> 	(nvptx_output_call_insn): Ditto.
> 	(TARGET_MANGLE_DECL_ASSEMBLER_NAME): Define.
>
> gcc/testsuite/
> 	* gcc.target/nvptx/rename-call.c: New test.
> 	* gcc.target/nvptx/rename-call-2.c: New test.
> 	* gcc.target/nvptx/asm-name.c: New test.

ok

nathan
diff mbox

Patch

diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index 1fc25e5..0c55976 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -273,7 +273,16 @@  nvptx_name_replacement (const char *name)
   for (size_t i = 0; i < ARRAY_SIZE (replacements) / 2; i++)
     if (!strcmp (name, replacements[2 * i]))
       return replacements[2 * i + 1];
-  return name;
+  return NULL;
+}
+
+/* Implement TARGET_MANGLE_DECL_ASSEMBLER_NAME.  */
+
+static tree
+nvptx_mangle_decl_assembler_name (tree ARG_UNUSED (decl), tree id)
+{
+  const char *name = nvptx_name_replacement (IDENTIFIER_POINTER (id));
+  return name ? get_identifier (name) : id;
 }
 
 /* If MODE should be treated as two registers of an inner mode, return
@@ -735,13 +744,8 @@  write_fn_proto (std::stringstream &s, bool is_defn,
   if (is_defn)
     /* Emit a declaration. The PTX assembler gets upset without it.   */
     name = write_fn_proto (s, false, name, decl);
-  else
-    {
-      /* Avoid repeating the name replacement.  */
-      name = nvptx_name_replacement (name);
-      if (name[0] == '*')
-	name++;
-    }
+  else if (name[0] == '*')
+    name++;
 
   write_fn_marker (s, is_defn, TREE_PUBLIC (decl), name);
 
@@ -822,7 +826,8 @@  write_fn_proto_from_insn (std::stringstream &s, const char *name,
     }
   else
     {
-      name = nvptx_name_replacement (name);
+      if (name[0] == '*')
+	name++;
       write_fn_marker (s, false, true, name);
       s << "\t.extern .func ";
     }
@@ -1976,7 +1981,6 @@  nvptx_output_call_insn (rtx_insn *insn, rtx result, rtx callee)
   if (decl)
     {
       const char *name = get_fnname_from_decl (decl);
-      name = nvptx_name_replacement (name);
       assemble_name (asm_out_file, name);
     }
   else
@@ -5124,6 +5128,8 @@  nvptx_goacc_reduction (gcall *call)
 #undef TARGET_NO_REGISTER_ALLOCATION
 #define TARGET_NO_REGISTER_ALLOCATION true
 
+#undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
+#define TARGET_MANGLE_DECL_ASSEMBLER_NAME nvptx_mangle_decl_assembler_name
 #undef TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO nvptx_encode_section_info
 #undef TARGET_RECORD_OFFLOAD_SYMBOL
diff --git a/gcc/testsuite/gcc.target/nvptx/asm-name.c b/gcc/testsuite/gcc.target/nvptx/asm-name.c
new file mode 100644
index 0000000..db52fff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/asm-name.c
@@ -0,0 +1,14 @@ 
+/* { dg-options "-std=gnu99" } */
+/* { dg-do assemble } */
+
+void foo(void) asm("bar");
+void foo_np()  asm("baz");
+
+void *p1 = foo;
+void *p2 = foo_np;
+
+void *r1() { return foo; }
+void *r2() { return foo_np; }
+
+void f1() { foo(); }
+void f2() { foo_np(); }
diff --git a/gcc/testsuite/gcc.target/nvptx/rename-call-2.c b/gcc/testsuite/gcc.target/nvptx/rename-call-2.c
new file mode 100644
index 0000000..230c680
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/rename-call-2.c
@@ -0,0 +1,12 @@ 
+/* { dg-options "-std=gnu99" } */
+/* { dg-do assemble } */
+
+/* Like rename-call.c, but using old-style prototype.  */
+
+void call();
+
+void *p = call;
+
+void *r() { return call; }
+
+void f() { call(); }
diff --git a/gcc/testsuite/gcc.target/nvptx/rename-call.c b/gcc/testsuite/gcc.target/nvptx/rename-call.c
new file mode 100644
index 0000000..d5685a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/rename-call.c
@@ -0,0 +1,16 @@ 
+/* { dg-options "-std=gnu99" } */
+/* { dg-do assemble } */
+
+/* Due to a bug in ptxas, calling a function named 'call' results in a "syntax
+   error" diagnostic. To work around that, nvptx backend renames it to
+   '__nvptx_call', but it used to do that inconsistently, and taking the address
+   of the function used the original name.  Check that it consistently works in
+   different contexts.  */
+
+void call(void);
+
+void *p = call;
+
+void *r() { return call; }
+
+void f() { call(); }