diff options
author | Tom de Vries <tdevries@suse.de> | 2020-10-10 17:22:01 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2020-10-10 23:34:24 +0200 |
commit | e88b04bda8a4bdcd03f867fc23f07d5d80f3f19a (patch) | |
tree | 4f4004e02b3ca3f64916c70efeed9cdb80a72936 /gcc/config | |
parent | db52bcfe4a0ef1bae9ed52b4e51af085f71c984d (diff) | |
download | gcc-e88b04bda8a4bdcd03f867fc23f07d5d80f3f19a.zip gcc-e88b04bda8a4bdcd03f867fc23f07d5d80f3f19a.tar.gz gcc-e88b04bda8a4bdcd03f867fc23f07d5d80f3f19a.tar.bz2 |
[nvptx] Replace dots in function names
When function splitting clones a function sinf in the host compiler, the clone
is callled sinf.part.0. However, ptx does not allows dots in identifiers, so
we run into:
...
ptxas test.o, line 23; fatal : Parsing error near '.part': syntax error
ptxas fatal : Ptx assembly aborted due to errors
nvptx-as: ptxas returned 255 exit status
...
Rename such functions by replacing the dots with dollar signs.
Tested check-gcc on nvptx.
Tested libgomp on x86_64-linux with nvptx accelerator.
gcc/ChangeLog:
2020-10-10 Tom de Vries <tdevries@suse.de>
PR target/97318
* config/nvptx/nvptx.c (nvptx_replace_dot): New function.
(write_fn_proto, write_fn_proto_from_insn, nvptx_output_call_insn):
Use nvptx_replace_dot.
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/nvptx/nvptx.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index 0c1d6d1..1734947 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -368,6 +368,22 @@ nvptx_name_replacement (const char *name) return name; } +/* Return NULL if NAME contains no dot. Otherwise return a copy of NAME + with the dots replaced with dollar signs. */ + +static char * +nvptx_replace_dot (const char *name) +{ + if (strchr (name, '.') == NULL) + return NULL; + + char *p = xstrdup (name); + for (size_t i = 0; i < strlen (p); ++i) + if (p[i] == '.') + p[i] = '$'; + return p; +} + /* If MODE should be treated as two registers of an inner mode, return that inner mode. Otherwise return VOIDmode. */ @@ -926,7 +942,16 @@ static void write_fn_proto (std::stringstream &s, bool is_defn, const char *name, const_tree decl) { - name = nvptx_name_replacement (name); + const char *replacement = nvptx_name_replacement (name); + char *replaced_dots = NULL; + if (replacement != name) + name = replacement; + else + { + replaced_dots = nvptx_replace_dot (name); + if (replaced_dots) + name = replaced_dots; + } if (name[0] == '*') name++; @@ -935,6 +960,9 @@ write_fn_proto (std::stringstream &s, bool is_defn, write_fn_proto_1 (s, false, name, decl); write_fn_proto_1 (s, is_defn, name, decl); + + if (replaced_dots) + XDELETE (replaced_dots); } /* Construct a function declaration from a call insn. This can be @@ -946,6 +974,8 @@ static void write_fn_proto_from_insn (std::stringstream &s, const char *name, rtx result, rtx pat) { + char *replaced_dots = NULL; + if (!name) { s << "\t.callprototype "; @@ -953,7 +983,15 @@ write_fn_proto_from_insn (std::stringstream &s, const char *name, } else { - name = nvptx_name_replacement (name); + const char *replacement = nvptx_name_replacement (name); + if (replacement != name) + name = replacement; + else + { + replaced_dots = nvptx_replace_dot (name); + if (replaced_dots) + name = replaced_dots; + } write_fn_marker (s, false, true, name); s << "\t.extern .func "; } @@ -962,6 +1000,8 @@ write_fn_proto_from_insn (std::stringstream &s, const char *name, write_return_mode (s, true, GET_MODE (result)); s << name; + if (replaced_dots) + XDELETE (replaced_dots); int arg_end = XVECLEN (pat, 0); for (int i = 1; i < arg_end; i++) @@ -2467,9 +2507,20 @@ nvptx_output_call_insn (rtx_insn *insn, rtx result, rtx callee) if (decl) { + char *replaced_dots = NULL; const char *name = get_fnname_from_decl (decl); - name = nvptx_name_replacement (name); + const char *replacement = nvptx_name_replacement (name); + if (replacement != name) + name = replacement; + else + { + replaced_dots = nvptx_replace_dot (name); + if (replaced_dots) + name = replaced_dots; + } assemble_name (asm_out_file, name); + if (replaced_dots) + XDELETE (replaced_dots); } else output_address (VOIDmode, callee); |