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

Reply via email to