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/ChangeLog: * common.opt (-foffload=): Update description. (-foffload-options=): New. * doc/invoke.texi (C Language Options): Document -foffload and -foffload-options. * gcc.c (check_offload_target_name): New, split off from handle_foffload_option. (check_foffload_target_names): New. (handle_foffload_option): Handle -foffload=default. (driver_handle_option): Update for -foffload-options. * lto-opts.c (lto_write_options): Use -foffload-options instead of -foffload. * lto-wrapper.c (merge_and_complain, append_offload_options): Likewise. * opts.c (common_handle_option): Likewise. libgomp/ChangeLog: * testsuite/libgomp.c-c++-common/reduction-16.c: Replace -foffload=nvptx-none= by -foffload-options=nvptx-none= to avoid disabling other offload targets. * testsuite/libgomp.c-c++-common/reduction-5.c: Likewise. * testsuite/libgomp.c-c++-common/reduction-6.c: Likewise. * testsuite/libgomp.c/target-44.c: Likewise. gcc/common.opt | 10 +- gcc/doc/invoke.texi | 41 +++++++ gcc/gcc.c | 121 +++++++++++++++++---- 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, 158 insertions(+), 37 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index 1dd4456e577..eaee74c580a 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2100,9 +2100,15 @@ fnon-call-exceptions Common Var(flag_non_call_exceptions) Optimization Support synchronous non-call exceptions. +; -foffload= is documented +; -foffload== is supported for backward compatibility foffload= -Common Driver Joined MissingArgError(options or targets missing after %qs) --foffload== Specify offloading targets and options for them. +Driver Joined MissingArgError(targets missing after %qs) +-foffload= Specify offloading targets + +foffload-options= +Common Driver Joined MissingArgError(options or targets=options missing after %qs) +-foffload== 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 bf529090d92..a9fd5fdc104 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -202,6 +202,7 @@ in the following sections. -fno-builtin -fno-builtin-@var{function} -fcond-mismatch @gol -ffreestanding -fgimple -fgnu-tm -fgnu89-inline -fhosted @gol -flax-vector-conversions -fms-extensions @gol +-foffload=@var{arg} -foffload-options=@var{arg} @gol -fopenacc -fopenacc-dim=@var{geom} @gol -fopenmp -fopenmp-simd @gol -fpermitted-flt-eval-methods=@var{standard} @gol @@ -2627,6 +2628,46 @@ fields within structs/unions}, for details. Note that this option is off for all targets except for x86 targets using ms-abi. +@item -foffload=disable +@itemx -foffload=default +@itemx -foffload=@var{target-list} +@opindex foffload +@cindex Offloading targets +@cindex OpenACC offloading targets +@cindex OpenMP offloading targets +Specify for which OpenMP and OpenACC offload targets code should be generated. +The default behavior, equivalent to @option{-foffload=default}, is to generate +code for all supported offload targets. The @option{-foffload=disable} form +generates code only for the host fallback, while +@option{-foffload=@var{target-list}} generates code only for the specified +comma-separated list of offload targets. + +Offload targets are specified in GCC's internal target-triplet format. You can +run the compiler with @option{-v} to show 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 options +@cindex OpenACC offloading options +@cindex OpenMP offloading options + +With @option{-foffload-options=@var{options}}, GCC passes the specified +@var{options} to the compilers for all enabled offloading targets. You can +specify options that apply only to a specific target or targets by using +the @option{-foffload-options=@var{target-list}=@var{options}} form. The +@var{target-list} is a comma-separated list in the same format as for the +@option{-foffload=} option. + +Typical command lines are + +@smallexample +-foffload-options=-lgfortran -foffload-options=-lm +-foffload-options="-lgfortran -lm" -foffload-options=nvptx-none=-latomic +-foffload-options=amdgcn-amdhsa=-march=gfx906 -foffload-options=-lm +@end smallexample + @item -fopenacc @opindex fopenacc @cindex OpenACC accelerator programming diff --git a/gcc/gcc.c b/gcc/gcc.c index af286400a4a..df9b2192873 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -3977,6 +3977,84 @@ 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 bool +check_offload_target_name (const char *target, ptrdiff_t len) +{ + const char *n, *c = OFFLOAD_TARGETS; + 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) + { + char *s; + auto_vec candidates; + char *cand = (char *) alloca (strlen (OFFLOAD_TARGETS) + 1); + c = OFFLOAD_TARGETS; + while (c) + { + n = strchr (c, ','); + if (n == NULL) + n = strchr (c, '\0'); + strncpy (cand, c, n - c); + cand[n - c] = '\0'; + candidates.safe_push (cand); + c = *n ? n + 1 : NULL; + } + error ("GCC is not configured to support %q.*s as offload target", + len, target); + const char *hint = candidates_list_and_hint (target, s, candidates); + if (hint) + inform (UNKNOWN_LOCATION, + "valid offload targets are: %s; did you mean %qs?", s, hint); + else + inform (UNKNOWN_LOCATION, "valid offload targets are: %s", s); + XDELETEVEC (s); + return false; + } + return true; +} + +/* 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; + + /* Retain non-supported targets after printing an error as those will not + be processed; each enabled target only processes its triplet. */ + check_offload_target_name (cur, next - cur); + cur = next + 1; + } +} + /* Parse -foffload option argument. */ static void @@ -4006,34 +4084,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 (strcmp (target, "disable") == 0) + /* Reset offloading list and continue. */ + if (strcmp (target, "default") == 0) { free (offload_targets); - offload_targets = xstrdup (""); - break; + offload_targets = NULL; + goto next_item; } - /* Check that GCC is configured to support the offload target. */ - c = OFFLOAD_TARGETS; - while (c) + /* If 'disable' is passed to the option, clean the list of + offload targets and return, even if more targets follow. + Likewise if GCC is not configured to support that offload target. */ + if (strcmp (target, "disable") == 0 + || !check_offload_target_name (target, next - cur)) { - 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 = xstrdup (""); + return; } - if (!c) - fatal_error (input_location, - "GCC is not configured to support %s as offload target", - target); - if (!offload_targets) { offload_targets = target; @@ -4067,7 +4136,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 +4568,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 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 66262c5b707..f159bb35130 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2724,7 +2724,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 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