summaryrefslogtreecommitdiff
path: root/gcc/gcc.c
diff options
context:
space:
mode:
authorkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-13 13:54:07 +0000
committerkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-13 13:54:07 +0000
commit38e21583d174a96a85786dd8d63d465e9e9e3391 (patch)
tree2fe44e0f530c8b4cf77e4ce8d2d53f000fba9744 /gcc/gcc.c
parent995b27b9592c984d7fcd8d1efb4d1a0db248e507 (diff)
downloadgcc-38e21583d174a96a85786dd8d63d465e9e9e3391.tar.gz
[PATCH 6/7] OpenMP 4.0 offloading infrastructure: option handling.
gcc/ * common.opt (foffload, foffload-abi): New options. * config/i386/i386.c (ix86_offload_options): New static function. (TARGET_OFFLOAD_OPTIONS): Define. * coretypes.h (enum offload_abi): New enum. * doc/tm.texi: Regenerate. * doc/tm.texi.in (TARGET_OFFLOAD_OPTIONS): Document. * gcc.c (offload_targets): New static variable. (handle_foffload_option): New static function. (driver_handle_option): Handle OPT_foffload_. (driver::maybe_putenv_OFFLOAD_TARGETS): Set OFFLOAD_TARGET_NAMES according to offload_targets. * hooks.c (hook_charptr_void_null): New hook. * hooks.h (hook_charptr_void_null): Declare. * lto-opts.c: Include lto-section-names.h. (lto_write_options): Append options from target offload_options hook and store them to offload_lto section. Do not store target-specific, driver and diagnostic options in offload_lto section. * lto-wrapper.c (merge_and_complain): Handle OPT_foffload_ and OPT_foffload_abi_. (append_compiler_options, append_linker_options) (append_offload_options): New static functions. (compile_offload_image): Add new arguments with options. Call append_compiler_options and append_offload_options. (compile_images_for_offload_targets): Add new arguments with options. (find_and_merge_options): New static function. (run_gcc): Outline options handling into the new functions: find_and_merge_options, append_compiler_options, append_linker_options. * opts.c (common_handle_option): Don't handle OPT_foffload_. Forbid OPT_foffload_abi_ for non-offload compiler. * target.def (offload_options): New target hook. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217493 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r--gcc/gcc.c108
1 files changed, 105 insertions, 3 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c
index abadfbf2e93..4422fa038e8 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -159,6 +159,10 @@ static const char *const spec_version = DEFAULT_TARGET_VERSION;
static const char *spec_machine = DEFAULT_TARGET_MACHINE;
static const char *spec_host_machine = DEFAULT_REAL_TARGET_MACHINE;
+/* List of offload targets. */
+
+static char *offload_targets = NULL;
+
/* Nonzero if cross-compiling.
When -b is used, the value comes from the `specs' file. */
@@ -3358,6 +3362,92 @@ driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
static const char *spec_lang = 0;
static int last_language_n_infiles;
+/* Parse -foffload option argument. */
+
+static void
+handle_foffload_option (const char *arg)
+{
+ const char *c, *cur, *n, *next, *end;
+ char *target;
+
+ /* If option argument starts with '-' then no target is specified and we
+ do not need to parse it. */
+ if (arg[0] == '-')
+ return;
+
+ end = strchrnul (arg, '=');
+ cur = arg;
+
+ while (cur < end)
+ {
+ next = strchrnul (cur, ',');
+ next = (next > end) ? end : next;
+
+ target = XNEWVEC (char, next - cur + 1);
+ strncpy (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)
+ {
+ free (offload_targets);
+ offload_targets = xstrdup ("");
+ break;
+ }
+
+ /* Check that GCC is configured to support the offload target. */
+ c = OFFLOAD_TARGETS;
+ while (c)
+ {
+ n = strchrnul (c, ',');
+
+ if (strlen (target) == (size_t) (n - c)
+ && strncmp (target, c, n - c) == 0)
+ break;
+
+ c = *n ? n + 1 : NULL;
+ }
+
+ if (!c)
+ fatal_error ("GCC is not configured to support %s as offload target",
+ target);
+
+ if (!offload_targets)
+ offload_targets = xstrdup (target);
+ else
+ {
+ /* Check that the target hasn't already presented in the list. */
+ c = offload_targets;
+ do
+ {
+ n = strchrnul (c, ':');
+
+ if (strlen (target) == (size_t) (n - c)
+ && strncmp (c, target, n - c) == 0)
+ break;
+
+ c = n + 1;
+ }
+ while (*n);
+
+ /* If duplicate is not found, append the target to the list. */
+ if (c > n)
+ {
+ offload_targets
+ = XRESIZEVEC (char, offload_targets,
+ strlen (offload_targets) + strlen (target) + 2);
+ if (strlen (offload_targets) != 0)
+ strcat (offload_targets, ":");
+ strcat (offload_targets, target);
+ }
+ }
+
+ cur = next + 1;
+ XDELETEVEC (target);
+ }
+}
+
/* Handle a driver option; arguments and return value as for
handle_option. */
@@ -3735,6 +3825,10 @@ driver_handle_option (struct gcc_options *opts,
flag_wpa = "";
break;
+ case OPT_foffload_:
+ handle_foffload_option (arg);
+ break;
+
default:
/* Various driver options need no special processing at this
point, having been handled in a prescan above or being
@@ -7252,14 +7346,22 @@ driver::maybe_putenv_COLLECT_LTO_WRAPPER () const
void
driver::maybe_putenv_OFFLOAD_TARGETS () const
{
- if (strlen (OFFLOAD_TARGETS) > 0)
+ const char *targets = offload_targets;
+
+ /* If no targets specified by -foffload, use all available targets. */
+ if (!targets)
+ targets = OFFLOAD_TARGETS;
+
+ if (strlen (targets) > 0)
{
obstack_grow (&collect_obstack, "OFFLOAD_TARGET_NAMES=",
sizeof ("OFFLOAD_TARGET_NAMES=") - 1);
- obstack_grow (&collect_obstack, OFFLOAD_TARGETS,
- strlen (OFFLOAD_TARGETS) + 1);
+ obstack_grow (&collect_obstack, targets,
+ strlen (targets) + 1);
xputenv (XOBFINISH (&collect_obstack, char *));
}
+
+ free (offload_targets);
}
/* Reject switches that no pass was interested in. */