[PATCH] nvptx backend: fix and streamline symbol renaming
Alexander Monakov
amonakov@ispras.ru
Thu Mar 31 11:32:00 GMT 2016
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
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(); }
--
1.8.3.1
More information about the Gcc-patches
mailing list