On Fri, 6 Nov 2015, Bernd Schmidt wrote: > On 10/30/2015 05:44 PM, Alexander Monakov wrote: > > + /* Ignore "omp target entrypoint" here: OpenMP target region functions > > are > > + called from gomp_nvptx_main. The corresponding kernel entry is > > emitted > > + from write_omp_entry. */ > > } > > I'm probably confused, but didn't we agree that this should be changed so that > the entry point isn't gomp_nvptx_main but instead something that wraps a call > to that function?
Yes, we did agree to that, and I've implemented that locally. I didn't resend the patch series yet, but for clarity I'm pasting the corresponding patch below. As you'll see, there's no contradiction because... > This patch creates a new "omp target entrypoint" annotation that appears not > to be used - it would be better to just not annotate a function if it's not > going to need entrypoint treatment. IMO a single type of attribute should be > sufficient for that. ... I need to examine "omp target entrypoint" in a different place -- not in write_as_kernel -- to invoke write_omp_entry (new function). To clarify, when a function 'main$_omp_fn$0' has "omp target entrypoint", the following patch renames it to 'main$_omp_fn$0$impl' and emits an entry-point wrapper with the original name that invokes the original -- now renamed -- function via gomp_nvptx_main. Alexander diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index 15efc26..b17e5a9 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -596,6 +596,45 @@ nvptx_init_axis_predicate (FILE *file, int regno, const char *name) fprintf (file, "\t}\n"); } +/* Emit kernel NAME for function ORIG outlined for an OpenMP 'target' region: + + extern void gomp_nvptx_main (void (*fn)(void*), void *fnarg); + void __attribute__((kernel)) NAME(void *arg) + { + gomp_nvptx_main (ORIG, arg); + } + ORIG itself should not be emitted as a PTX .entry function. */ + +static void +write_omp_entry (std::stringstream &s, const char *name, const char *orig) +{ + /* Pointer-sized PTX integer type, .u32 or .u64 depending on target ABI. */ + const char *sfx = nvptx_ptx_type_from_mode (Pmode, false); + + /* OpenMP target regions are entered via gomp_nvptx_main. */ + static bool gomp_nvptx_main_declared; + if (!gomp_nvptx_main_declared) + { + gomp_nvptx_main_declared = true; + s << "// BEGIN GLOBAL FUNCTION DECL: gomp_nvptx_main\n"; + s << ".extern .func gomp_nvptx_main"; + s << "(.param" << sfx << " %in_ar1, .param" << sfx << " %in_ar2);\n"; + } + s << ".visible .entry " << name << "(.param" << sfx << " %in_ar1)\n"; + s << "{\n"; + s << "\t.reg" << sfx << " %ar1;\n"; + s << "\tld.param" << sfx << " %ar1, [%in_ar1];\n"; + s << "\t{\n"; + s << "\t\t.param" << sfx << " %out_arg0;\n"; + s << "\t\t.param" << sfx << " %out_arg1;\n"; + s << "\t\tst.param" << sfx << " [%out_arg0], " << orig << ";\n"; + s << "\t\tst.param" << sfx << " [%out_arg1], %ar1;\n"; + s << "\t\tcall.uni gomp_nvptx_main, (%out_arg0, %out_arg1);\n"; + s << "\t}\n"; + s << "\tret;\n"; + s << "}\n"; +} + /* Implement ASM_DECLARE_FUNCTION_NAME. Writes the start of a ptx function, including local var decls and copies from the arguments to local regs. */ @@ -609,6 +648,14 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl) name = nvptx_name_replacement (name); std::stringstream s; + if (flag_openmp + && lookup_attribute ("omp target entrypoint", DECL_ATTRIBUTES (decl))) + { + char *buf = (char *) alloca (strlen (name) + sizeof ("$impl")); + sprintf (buf, "%s$impl", name); + write_omp_entry (s, name, buf); + name = buf; + } write_function_decl_and_comment (s, name, decl); s << "// BEGIN"; if (TREE_PUBLIC (decl))