On 17.06.21 23:57, Sandra Loosemore wrote:

On 6/17/21 1:40 PM, Jakub Jelinek wrote:
Could we introduce a different option which wouldn't imply enabling that
target:
-foffload-options=<target triplet list>=option

I think that works – in particular, if we do not document all
the legacy stuff but just how it should be used.

That includes not mentioning that disable and default can
be used in a list and that those can also take arguments.

I don't feel qualified to comment on the details of the behavior, but
separating the options and making them more orthogonal to one another
would certainly make things easier to document.  :-)

I fully concur.

Probably not fully polished, but I have attached a version for discussion.

One other thing I'd like to see in the docs is how to ask GCC what
offload targets it is configured to support by default.  This could be
put in a paragraph that also includes the language about how you need
to have the compilers for those offload targets installed too.

"gcc -v 2>&1 |grep OFFLOAD_TARGET_NAMES"  shows them.

Note that with the flags under discussion, you can modify
the output, e.g.
* "gcc -v -foffload=disable" removes it
* "gcc -v -foffload=nvptx-none" either gives an error (not supported) or
  just shows that single target.

 * * *

Installing:
Building oneself: "make install" – and everything is there

With a distributions, you need to find the name of the .rpm/.deb
package for the target your are interested in and then run
apt-get / yum / zypper / ...

Hence, when you normally build GCC as a user, for all configured offload
targets, their lto1 should be there - and if lto-wrapper cannot find it,
it aborts with a fatal error.
For distribution compilers, it usually just means that the optional
package is not installed – the missing lto1 should/is then just ignored,
That's the reason why GCC's configure script now has a flag
--enable-offload-defaulted to toggle between supporting optional packages
(distro use) and always errors (normal use).

If you want to know how to build it, have a lot of fun with incomplete
documentation and a look at https://gcc.gnu.org/wiki/Offloading or
at the SUSE/Debian/Red Hat build scripts or g-t-s – and expect that
you won't finish soon ...

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
Add 'default' to -foffload=; document that flag [PR67300]

As -foffload={options,targets,targets=options} is very convoluted,
it has been split into -foffload=targets (supporting the old syntax
for backward compatibilty) and -foffload-options={options,target=options}.

Only the new syntax is documented.

Additionally, -foffload=default is supported, which can reset the
devices after -foffload=disable / -foffload=targets to the default,
if needed.

 gcc/common.opt                                     |  10 ++-
 gcc/doc/invoke.texi                                |  41 +++++++++
 gcc/gcc.c                                          | 100 +++++++++++++++++----
 gcc/lto-opts.c                                     |   3 +-
 gcc/lto-wrapper.c                                  |  10 +--
 gcc/opts.c                                         |   2 +-
 .../testsuite/libgomp.c-c++-common/reduction-16.c  |   2 +-
 .../testsuite/libgomp.c-c++-common/reduction-5.c   |   2 +-
 .../testsuite/libgomp.c-c++-common/reduction-6.c   |   2 +-
 libgomp/testsuite/libgomp.c/target-44.c            |   2 +-
 10 files changed, 140 insertions(+), 34 deletions(-)

diff --git a/gcc/common.opt b/gcc/common.opt
index a1353e06bdc..a695a8c5964 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2095,9 +2095,15 @@ fnon-call-exceptions
 Common Var(flag_non_call_exceptions) Optimization
 Support synchronous non-call exceptions.
 
+; -foffload=<targets> is documented
+; -foffload=<targets>=<options> is supported for backward compatibility
 foffload=
-Common Driver Joined MissingArgError(options or targets missing after %qs)
--foffload=<targets>=<options>	Specify offloading targets and options for them.
+Driver Joined MissingArgError(targets missing after %qs)
+-foffload=<targets>	Specify offloading targets
+
+foffload-options=
+Common Driver Joined MissingArgError(options or targets=options missing after %qs)
+-foffload=<targets>=<options>	Specify options for the offloading targets
 
 foffload-abi=
 Common Joined RejectNegative Enum(offload_abi) Var(flag_offload_abi) Init(OFFLOAD_ABI_UNSET)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index af2ce189fae..82993fa2c1d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -204,6 +204,7 @@ in the following sections.
 -fhosted  -ffreestanding @gol
 -fopenacc  -fopenacc-dim=@var{geom} @gol
 -fopenmp  -fopenmp-simd @gol
+-foffload=@var{arg} -foffload-options=@var{arg} @gol
 -fms-extensions  -fplan9-extensions  -fsso-struct=@var{endianness} @gol
 -fallow-single-precision  -fcond-mismatch  -flax-vector-conversions @gol
 -fsigned-bitfields  -fsigned-char @gol
@@ -2639,6 +2640,46 @@ Enable handling of OpenMP's SIMD directives with @code{#pragma omp}
 in C/C++ and @code{!$omp} in Fortran. Other OpenMP directives
 are ignored.
 
+@item -foffload=disable
+@itemx -foffload=default
+@itemx -foffload=@var{target-list}
+@opindex foffload
+@cindex Offloading
+@cindex OpenACC
+@cindex OpenMP
+Specify for which offload targets code should be generated.  By default,
+code for all supported targets is generated.  Using
+@option{-foffload=disable} only code for the host fallback is
+generated, while @option{-foffload=}@var{target-list} generates code
+only for the specified comma-separated list of offload-targets triplets.
+To reset the value to the default, @option{-foffload=default} can be
+used.
+
+Note: Running the compiler with @option{-v} shows the list of
+configured offload targets under @code{OFFLOAD_TARGET_NAMES}.
+
+@item -foffload-options=@var{options}
+@itemx -foffload-options=@var{target-triplet-list}=@var{options}
+@opindex foffload
+@cindex Offloading
+@cindex OpenACC
+@cindex OpenMP
+
+Specify the options passed to the offload-target compiler. While using
+@option{-foffload-options=}@var{options} passes the options to all enabled
+offloading compiler,
+@option{-foffload-options=}@var{target-triplet-list}=@var{options} can
+be used to pass them only to the specified comma-separated list of
+target triplets.
+
+Typical commandlines are
+
+@smallexample
+-foffload=-lgfortran -foffload=-lm
+-foffload=-lm -foffload=nvptx-none=-latomic
+-foffload=amdgcn-amdhsa=-march=gfx906 -foffload=nvptx-none="-latomic -lm"
+@end smallexample
+
 @item -fgnu-tm
 @opindex fgnu-tm
 When the option @option{-fgnu-tm} is specified, the compiler
diff --git a/gcc/gcc.c b/gcc/gcc.c
index af286400a4a..203e6e5f8ed 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -3977,6 +3977,68 @@ driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
 static const char *spec_lang = 0;
 static int last_language_n_infiles;
 
+
+/* Check that GCC is configured to support the offload target.  */
+
+static void
+check_offload_target_name (const char *target, ptrdiff_t len)
+{
+  const char *n, *c = OFFLOAD_TARGETS;
+  char *target2 = NULL;
+  while (c)
+    {
+      n = strchr (c, ',');
+      if (n == NULL)
+	n = strchr (c, '\0');
+      if (len == n - c && strncmp (target, c, n - c) == 0)
+	break;
+      c = *n ? n + 1 : NULL;
+    }
+  if (!c)
+    {
+      if (target[len] != '\0')
+	{
+	  target2 = XNEWVEC (char, len + 1);
+	  memcpy (target2, target, len);
+	  target2[len] = '\0';
+	}
+      fatal_error (input_location,
+		 "GCC is not configured to support %qs as offload target",
+		 target2 ? target2 : target);
+      XDELETEVEC (target2);
+    }
+}
+
+/* Sanity check for -foffload-options.  */
+
+static void
+check_foffload_target_names (const char *arg)
+{
+  const char *cur, *next, *end;
+  /* If option argument starts with '-' then no target is specified and we
+     do not need to parse it.  */
+  if (arg[0] == '-')
+    return;
+  end = strchr (arg, '=');
+  if (end == NULL)
+    {
+      error ("%<=options%> missing after %<-foffload-options=target%>");
+      return;
+    }
+
+  cur = arg;
+  while (cur < end)
+    {
+      next = strchr (cur, ',');
+      if (next == NULL)
+	next = end;
+      next = (next > end) ? end : next;
+
+      check_offload_target_name (cur, next - cur);
+      cur = next + 1;
+   }
+}
+
 /* Parse -foffload option argument.  */
 
 static void
@@ -4006,33 +4068,25 @@ handle_foffload_option (const char *arg)
       memcpy (target, cur, next - cur);
       target[next - cur] = '\0';
 
-      /* If 'disable' is passed to the option, stop parsing the option and clean
-         the list of offload targets.  */
+      /* If 'disable' is passed to the option, clean the list of
+	 offload targets and return, even if more targets follow. */
       if (strcmp (target, "disable") == 0)
 	{
 	  free (offload_targets);
 	  offload_targets = xstrdup ("");
-	  break;
+	  return;
 	}
 
-      /* Check that GCC is configured to support the offload target.  */
-      c = OFFLOAD_TARGETS;
-      while (c)
+      /* Reset offloading list and continue.  */
+      if (strcmp (target, "default") == 0)
 	{
-	  n = strchr (c, ',');
-	  if (n == NULL)
-	    n = strchr (c, '\0');
-
-	  if (next - cur == n - c && strncmp (target, c, n - c) == 0)
-	    break;
-
-	  c = *n ? n + 1 : NULL;
+	  free (offload_targets);
+	  offload_targets = NULL;
+	  goto next_item;
 	}
 
-      if (!c)
-	fatal_error (input_location,
-		     "GCC is not configured to support %s as offload target",
-		     target);
+      /* Check that GCC is configured to support the offload target.  */
+      check_offload_target_name (target, next - cur);
 
       if (!offload_targets)
 	{
@@ -4067,7 +4121,7 @@ handle_foffload_option (const char *arg)
 	      memcpy (offload_targets + offload_targets_len, target, next - cur + 1);
 	    }
 	}
-
+next_item:
       cur = next + 1;
       XDELETEVEC (target);
     }
@@ -4499,8 +4553,16 @@ driver_handle_option (struct gcc_options *opts,
       flag_wpa = "";
       break;
 
+    case OPT_foffload_options_:
+      check_foffload_target_names (arg);
+      break;
+
     case OPT_foffload_:
       handle_foffload_option (arg);
+      if (arg[0] == '-' || NULL != strchr (arg, '='))
+	save_switch (concat ("-foffload-options=", arg, NULL),
+		     0, NULL, validated, true);
+      do_save = false;
       break;
 
     default:
diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c
index 6dd55b68072..9496b3c8e0b 100644
--- a/gcc/lto-opts.c
+++ b/gcc/lto-opts.c
@@ -174,7 +174,8 @@ lto_write_options (void)
 	 We do not need those.  The only exception is -foffload option, if we
 	 write it in offload_lto section.  Also drop all diagnostic options.  */
       if ((cl_options[option->opt_index].flags & (CL_DRIVER|CL_WARNING))
-	  && (!lto_stream_offload_p || option->opt_index != OPT_foffload_))
+	  && (!lto_stream_offload_p
+	      || option->opt_index != OPT_foffload_options_))
 	continue;
 
       for (j = 0; j < option->canonical_option_num_elements; ++j)
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 1c2643984f9..aae48aff100 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -453,7 +453,7 @@ merge_and_complain (vec<cl_decoded_option> decoded_options,
 	  break;
 
 
-	case OPT_foffload_:
+	case OPT_foffload_options_:
 	  decoded_options.safe_push (*foption);
 	  break;
 
@@ -833,7 +833,7 @@ append_offload_options (obstack *argv_obstack, const char *target,
       unsigned argc;
       cl_decoded_option *option = &options[i];
 
-      if (option->opt_index != OPT_foffload_)
+      if (option->opt_index != OPT_foffload_options_)
 	continue;
 
       /* If option argument starts with '-' then no target is specified.  That
@@ -844,11 +844,7 @@ append_offload_options (obstack *argv_obstack, const char *target,
       else
 	{
 	  opts = strchr (option->arg, '=');
-	  /* If there are offload targets specified, but no actual options,
-	     there is nothing to do here.  */
-	  if (!opts)
-	    continue;
-
+	  gcc_assert (opts);
 	  cur = option->arg;
 
 	  while (cur < opts)
diff --git a/gcc/opts.c b/gcc/opts.c
index 52e9e3a9df9..3a43dd43398 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2706,7 +2706,7 @@ common_handle_option (struct gcc_options *opts,
       /* Deferred.  */
       break;
 
-    case OPT_foffload_:
+    case OPT_foffload_options_:
       /* Deferred.  */
       break;
 
diff --git a/libgomp/testsuite/libgomp.c-c++-common/reduction-16.c b/libgomp/testsuite/libgomp.c-c++-common/reduction-16.c
index 0eea73b144b..4bf62c3828f 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/reduction-16.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/reduction-16.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-additional-options "-foffload=nvptx-none=-latomic" { target offload_target_nvptx } } */
+/* { dg-additional-options "-foffload-options=nvptx-none=-latomic" { target offload_target_nvptx } } */
 
 #include <stdlib.h>
 
diff --git a/libgomp/testsuite/libgomp.c-c++-common/reduction-5.c b/libgomp/testsuite/libgomp.c-c++-common/reduction-5.c
index 31fa2670312..52f23e35b9a 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/reduction-5.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/reduction-5.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-foffload=nvptx-none=-latomic" { target { offload_target_nvptx } } } */
+/* { dg-additional-options "-foffload-options=nvptx-none=-latomic" { target { offload_target_nvptx } } } */
 /* C / C++'s logical AND and OR operators take any scalar argument
    which compares (un)equal to 0 - the result 1 or 0 and of type int.
 
diff --git a/libgomp/testsuite/libgomp.c-c++-common/reduction-6.c b/libgomp/testsuite/libgomp.c-c++-common/reduction-6.c
index 727e11e4edf..62e81506bdd 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/reduction-6.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/reduction-6.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-foffload=nvptx-none=-latomic" { target { offload_target_nvptx } } } */
+/* { dg-additional-options "-foffload-options=nvptx-none=-latomic" { target { offload_target_nvptx } } } */
 /* C / C++'s logical AND and OR operators take any scalar argument
    which compares (un)equal to 0 - the result 1 or 0 and of type int.
 
diff --git a/libgomp/testsuite/libgomp.c/target-44.c b/libgomp/testsuite/libgomp.c/target-44.c
index b95e807a114..a5da81d7e23 100644
--- a/libgomp/testsuite/libgomp.c/target-44.c
+++ b/libgomp/testsuite/libgomp.c/target-44.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-foffload=nvptx-none=-latomic" { target { offload_target_nvptx } } } */
+/* { dg-additional-options "-foffload-options=nvptx-none=-latomic" { target { offload_target_nvptx } } } */
 
 #include <stdlib.h>
 

Reply via email to