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))