This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: nvptx offloading patches [3/n], i386 bits RFD


On 11/03/2014 11:27 PM, Jeff Law wrote:
On 11/01/14 05:57, Bernd Schmidt wrote:
This is not against current trunk; it applies to gomp-4_0-branch where
it is one of the necessary parts to make offloading x86->nvptx work. The
issue is that the LTO file format depends on the machine_modes enum, it
needs to match between host and offload target. The easiest way to do
this is to just use the host-modes.def when compiling an offload
compiler.

Ports that want to be hosts for offloading may need to modify their
modes.def. The patch below contains changes to i386-modes.def which
modifies XFmode depending on a target switch. I'm not actually entirely
sure what to do about this. Do we want to make this flag an error when
offloading is enabled? Or maybe add float format support to the
-foffload-abi option?

Thoughts? Ok for the first part of the patch once the other offloading
patches have gone in (bootstrapped and tested on x86_64-linux)?
It feels like we've got another real distinction to make.  We've had
host, build & target and they're all independent.  It feels like we need
offload target and better separate between target and offload target.
Then we need to figure out the places where we've got bleed-out.

Is this a question of terminology? I agree that saying "offload host" when we'd normally be calling it the "target" is confusing, but it's difficult to come up with better names.

Offload host and target are not quite independent - when it's implemented through LTO at least there has to be a fairly close agreement even down to machine modes, which is why a patch like this is necessary.

Not sure how to deal with this any further out than the immediate term
than using a hack like this. Though I'd prefer to avoid the #ifdef as it
seems to me this shouldn't be baked in at build/configure time.

Yeah, I'm not expecting the i386 part to go in quite as-is. For reference I'm including the offload-abi patch - Ilya is submitting this along with other option changes. One possibility would be to print and recognize strings such as lp64D128 or lp64D96 which would include information about the size of long double. Somehow though I can't really bring myself to believe that -mlong-double128 is a real use case with offloading so we might just disallow the combination.

CCing Uros in case he has an opinion.


Bernd

Index: gcc/common.opt
===================================================================
--- gcc/common.opt.orig
+++ gcc/common.opt
@@ -1601,6 +1601,19 @@ fnon-call-exceptions
 Common Report Var(flag_non_call_exceptions) Optimization
 Support synchronous non-call exceptions
 
+foffload-abi=
+Common Joined RejectNegative Enum(offload_abi) Var(flag_offload_abi) Init(OFFLOAD_ABI_UNSET)
+-foffload-abi=[lp64|ilp32]	Set the ABI to use in an offload compiler
+
+Enum
+Name(offload_abi) Type(enum offload_abi) UnknownError(unknown offload ABI %qs)
+
+EnumValue
+Enum(offload_abi) String(ilp32) Value(OFFLOAD_ABI_ILP32)
+
+EnumValue
+Enum(offload_abi) String(lp64) Value(OFFLOAD_ABI_LP64)
+
 fomit-frame-pointer
 Common Report Var(flag_omit_frame_pointer) Optimization
 When possible do not generate stack frames
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c.orig
+++ gcc/config/i386/i386.c
@@ -4261,6 +4261,15 @@ ix86_option_override (void)
   register_pass (&insert_vzeroupper_info);
 }
 
+/* Implement the TARGET_OFFLOAD_OPTIONS hook.  */
+static char *
+ix86_offload_options (void)
+{
+  if (TARGET_LP64)
+    return xstrdup ("-foffload-abi=lp64");
+  return xstrdup ("-foffload-abi=ilp32");
+}
+
 /* Update register usage after having seen the compiler flags.  */
 
 static void
@@ -47142,6 +47151,10 @@ ix86_atomic_assign_expand_fenv (tree *ho
 #define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
   ix86_float_exceptions_rounding_supported_p
 
+#undef TARGET_OFFLOAD_OPTIONS
+#define TARGET_OFFLOAD_OPTIONS \
+  ix86_offload_options
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-i386.h"
Index: gcc/coretypes.h
===================================================================
--- gcc/coretypes.h.orig
+++ gcc/coretypes.h
@@ -111,6 +111,12 @@ enum tls_model {
   TLS_MODEL_LOCAL_EXEC
 };
 
+enum offload_abi {
+  OFFLOAD_ABI_UNSET,
+  OFFLOAD_ABI_LP64,
+  OFFLOAD_ABI_ILP32
+};
+
 /* Types of unwind/exception handling info that can be generated.  */
 
 enum unwind_info_type
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi.orig
+++ gcc/doc/tm.texi
@@ -11446,3 +11446,12 @@ Used when offloaded functions are seen i
 sections are available.  It is called once for each symbol that must be
 recorded in the offload function and variable table.
 @end deftypefn
+
+@deftypefn {Target Hook} {char *} TARGET_OFFLOAD_OPTIONS (void)
+Used when writing out the list of options into an LTO file.  It should
+translate any relevant target-specific options (such as the ABI in use)
+into one of the @option{-foffload} options that exist as a common interface
+to express such options. It should return a string containing these options,
+separated by spaces, which the caller will free.
+
+@end deftypefn
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in.orig
+++ gcc/doc/tm.texi.in
@@ -8427,3 +8427,5 @@ and the associated definitions of those
 @hook TARGET_ATOMIC_ASSIGN_EXPAND_FENV
 
 @hook TARGET_RECORD_OFFLOAD_SYMBOL
+
+@hook TARGET_OFFLOAD_OPTIONS
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c.orig
+++ gcc/hooks.c
@@ -373,12 +373,19 @@ hook_tree_tree_tree_tree_3rd_identity (t
   return c;
 }
 
-/* Generic hook that takes no arguments and returns a NULL string.  */
+/* Generic hook that takes no arguments and returns a NULL const string.  */
 const char *
 hook_constcharptr_void_null (void)
 {
   return NULL;
 }
+
+/* Generic hook that takes no arguments and returns a NULL string.  */
+char *
+hook_charptr_void_null (void)
+{
+  return NULL;
+}
 
 /* Generic hook that takes a tree and returns a NULL string.  */
 const char *
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h.orig
+++ gcc/hooks.h
@@ -101,6 +101,7 @@ extern rtx hook_rtx_rtx_identity (rtx);
 extern rtx hook_rtx_rtx_null (rtx);
 extern rtx hook_rtx_tree_int_null (tree, int);
 
+extern char *hook_charptr_void_null (void);
 extern const char *hook_constcharptr_void_null (void);
 extern const char *hook_constcharptr_const_tree_null (const_tree);
 extern const char *hook_constcharptr_const_rtx_null (const_rtx);
Index: gcc/lto-opts.c
===================================================================
--- gcc/lto-opts.c.orig
+++ gcc/lto-opts.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.
 #include "common/common-target.h"
 #include "diagnostic.h"
 #include "lto-streamer.h"
+#include "lto-section-names.h"
 #include "toplev.h"
 
 /* Append the option piece OPT to the COLLECT_GCC_OPTIONS string
@@ -130,6 +131,22 @@ lto_write_options (void)
     append_to_collect_gcc_options (&temporary_obstack, &first_p,
 			       "-fno-strict-overflow");
 
+  if (strcmp (section_name_prefix, OMP_SECTION_NAME_PREFIX) == 0)
+    {
+      char *offload_opts = targetm.offload_options ();
+      char *offload_ptr = offload_opts;
+      while (offload_ptr)
+	{
+	  char *next = strchr (offload_ptr, ' ');
+	  if (next)
+	    *next++ = '\0';
+	  append_to_collect_gcc_options (&temporary_obstack, &first_p,
+					 offload_ptr);
+	  offload_ptr = next;
+	}
+      free (offload_opts);
+    }
+
   /* Output explicitly passed options.  */
   for (i = 1; i < save_decoded_options_count; ++i)
     {
@@ -153,6 +170,10 @@ lto_write_options (void)
       if (!(cl_options[option->opt_index].flags & (CL_COMMON|CL_TARGET|CL_LTO)))
 	continue;
 
+      if ((cl_options[option->opt_index].flags & CL_TARGET)
+	  && strcmp (section_name_prefix, OMP_SECTION_NAME_PREFIX) == 0)
+	continue;
+
       /* Drop options created from the gcc driver that will be rejected
 	 when passed on to the driver again.  */
       if (cl_options[option->opt_index].cl_reject_driver)
Index: gcc/lto-wrapper.c
===================================================================
--- gcc/lto-wrapper.c.orig
+++ gcc/lto-wrapper.c
@@ -282,6 +282,17 @@ merge_and_complain (struct cl_decoded_op
 		   foption->orig_option_with_args_text);
 	  break;
 
+	case OPT_foffload_abi_:
+	  for (j = 0; j < *decoded_options_count; ++j)
+	    if ((*decoded_options)[j].opt_index == foption->opt_index)
+	      break;
+	  if (j == *decoded_options_count)
+	    append_option (decoded_options, decoded_options_count, foption);
+	  else if (foption->value != (*decoded_options)[j].value)
+	    fatal ("Option %s not used consistently in all LTO input files",
+		   foption->orig_option_with_args_text);
+	  break;
+
 	case OPT_O:
 	case OPT_Ofast:
 	case OPT_Og:
@@ -414,6 +425,109 @@ parse_env_var (const char *str, char ***
   return num;
 }
 
+static void
+append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
+			 unsigned int count)
+{
+  /* Append compiler driver arguments as far as they were merged.  */
+  for (unsigned int j = 1; j < count; ++j)
+    {
+      struct cl_decoded_option *option = &opts[j];
+
+      /* File options have been properly filtered by lto-opts.c.  */
+      switch (option->opt_index)
+	{
+	  /* Drop arguments that we want to take from the link line.  */
+	case OPT_flto_:
+	case OPT_flto:
+	case OPT_flto_partition_:
+	  continue;
+
+	default:
+	  break;
+	}
+
+      /* For now do what the original LTO option code was doing - pass
+	 on any CL_TARGET flag and a few selected others.  */
+      switch (option->opt_index)
+	{
+	case OPT_fPIC:
+	case OPT_fpic:
+	case OPT_fPIE:
+	case OPT_fpie:
+	case OPT_fcommon:
+	case OPT_fexceptions:
+	case OPT_fnon_call_exceptions:
+	case OPT_fgnu_tm:
+	case OPT_freg_struct_return:
+	case OPT_fpcc_struct_return:
+	case OPT_fshort_double:
+	case OPT_ffp_contract_:
+	case OPT_fwrapv:
+	case OPT_ftrapv:
+	case OPT_fstrict_overflow:
+	case OPT_foffload_abi_:
+	case OPT_O:
+	case OPT_Ofast:
+	case OPT_Og:
+	case OPT_Os:
+	  break;
+
+	default:
+	  if (!(cl_options[option->opt_index].flags & CL_TARGET))
+	    continue;
+	}
+
+      /* Pass the option on.  */
+      for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
+	obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
+    }
+}
+
+static void
+append_linker_options (obstack *argv_obstack, struct cl_decoded_option *opts,
+		       unsigned int count, bool include_target_options)
+{
+  /* Append linker driver arguments.  Compiler options from the linker
+     driver arguments will override / merge with those from the compiler.  */
+  for (unsigned int j = 1; j < count; ++j)
+    {
+      struct cl_decoded_option *option = &opts[j];
+
+      /* Do not pass on frontend specific flags not suitable for lto.  */
+      if (!(cl_options[option->opt_index].flags
+	    & (CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO)))
+	continue;
+
+      if ((cl_options[option->opt_index].flags & CL_TARGET)
+	  && !include_target_options)
+	continue;
+
+      switch (option->opt_index)
+	{
+	case OPT_o:
+	case OPT_flto_:
+	case OPT_flto:
+	  /* We've handled these LTO options, do not pass them on.  */
+	  continue;
+
+	case OPT_freg_struct_return:
+	case OPT_fpcc_struct_return:
+	case OPT_fshort_double:
+	  /* Ignore these, they are determined by the input files.
+	     ???  We fail to diagnose a possible mismatch here.  */
+	  continue;
+
+	default:
+	  break;
+	}
+
+      /* Pass the option on.  */
+      for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
+	obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
+    }
+}
+
 /* Check whether NAME can be accessed in MODE.  This is like access,
    except that it never considers directories to be executable.  */
 
@@ -440,7 +554,11 @@ access_check (const char *name, int mode
 
 static char*
 prepare_target_image (const char *target, const char *compiler_path,
-		      unsigned in_argc, char *in_argv[])
+		      unsigned in_argc, char *in_argv[],
+		      struct cl_decoded_option *compiler_opts,
+		      unsigned int compiler_opt_count,
+		      struct cl_decoded_option * /*linker_opts */,
+		      unsigned int /*linker_opt_count*/)
 {
   const char **argv;
   struct obstack argv_obstack;
@@ -469,8 +587,6 @@ prepare_target_image (const char *target
   /* Generate temp file name.  */
   filename = make_temp_file (".target.o");
 
-  /* --------------------------------------  */
-  /* Run gcc for target.  */
   obstack_init (&argv_obstack);
   obstack_ptr_grow (&argv_obstack, compiler);
   obstack_ptr_grow (&argv_obstack, "-o");
@@ -479,6 +595,8 @@ prepare_target_image (const char *target
   for (i = 1; i < in_argc; ++i)
     if (strncmp (in_argv[i], "-fresolution=", sizeof ("-fresolution=") - 1))
       obstack_ptr_grow (&argv_obstack, in_argv[i]);
+
+  append_compiler_options (&argv_obstack, compiler_opts, compiler_opt_count);
   obstack_ptr_grow (&argv_obstack, NULL);
 
   argv = XOBFINISH (&argv_obstack, const char **);
@@ -501,7 +619,11 @@ prepare_target_image (const char *target
    array.  */
 
 static void
-compile_images_for_openmp_targets (unsigned in_argc, char *in_argv[])
+compile_images_for_openmp_targets (unsigned in_argc, char *in_argv[],
+				   struct cl_decoded_option *compiler_opts,
+				   unsigned int compiler_opt_count,
+				   struct cl_decoded_option *linker_opts,
+				   unsigned int linker_opt_count)
 {
   char *target_names;
   char **names;
@@ -523,8 +645,10 @@ compile_images_for_openmp_targets (unsig
   offload_names = XCNEWVEC (char *, num_targets + 1);
   for (unsigned i = 0; i < num_targets; i++)
     {
-      offload_names[i] = prepare_target_image (names[i], compiler_path,
-					       in_argc, in_argv);
+      offload_names[i]
+	= prepare_target_image (names[i], compiler_path, in_argc, in_argv,
+				compiler_opts, compiler_opt_count,
+				linker_opts, linker_opt_count);
       if (!offload_names[i])
 	fatal_perror ("Problem with building target image for %s.\n", names[i]);
     }
@@ -592,6 +716,74 @@ find_ompbeginend (void)
   free_array_of_ptrs ((void**) paths, n_paths);
 }
 
+/* A subroutine of run_gcc.  Examine the open file FD for lto sections with
+   name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS
+   and OPT_COUNT.  Return true if we found a matchingn section, false
+   otherwise.  COLLECT_GCC holds the value of the environment variable with
+   the same name.  */
+
+static bool
+find_and_merge_options (int fd, off_t file_offset, const char *prefix,
+			struct cl_decoded_option **opts,
+			unsigned int *opt_count, const char *collect_gcc)
+{
+  off_t offset, length;
+  char *data;
+  char *fopts;
+  const char *errmsg;
+  int err;
+  struct cl_decoded_option *fdecoded_options = *opts;
+  unsigned int fdecoded_options_count = *opt_count;
+
+  simple_object_read *sobj;
+  sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
+				   &errmsg, &err);
+  if (!sobj)
+    return false;
+
+  char *secname = XNEWVEC (char, strlen (prefix) + 6);
+  strcpy (secname, prefix);
+  strcat (secname, ".opts");
+  if (!simple_object_find_section (sobj, secname, &offset, &length,
+				   &errmsg, &err))
+    {
+      simple_object_release_read (sobj);
+      return false;
+    }
+
+  lseek (fd, file_offset + offset, SEEK_SET);
+  data = (char *)xmalloc (length);
+  read (fd, data, length);
+  fopts = data;
+  do
+    {
+      struct cl_decoded_option *f2decoded_options;
+      unsigned int f2decoded_options_count;
+      get_options_from_collect_gcc_options (collect_gcc,
+					    fopts, CL_LANG_ALL,
+					    &f2decoded_options,
+					    &f2decoded_options_count);
+      if (!fdecoded_options)
+	{
+	  fdecoded_options = f2decoded_options;
+	  fdecoded_options_count = f2decoded_options_count;
+	}
+      else
+	merge_and_complain (&fdecoded_options,
+			    &fdecoded_options_count,
+			    f2decoded_options, f2decoded_options_count);
+
+      fopts += strlen (fopts) + 1;
+    }
+  while (fopts - data < length);
+
+  free (data);
+  simple_object_release_read (sobj);
+  *opts = fdecoded_options;
+  *opt_count = fdecoded_options_count;
+  return true;
+}
+
 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
 
 static void
@@ -607,7 +799,9 @@ run_gcc (unsigned argc, char *argv[])
   int jobserver = 0;
   bool no_partition = false;
   struct cl_decoded_option *fdecoded_options = NULL;
+  struct cl_decoded_option *omp_fdecoded_options = NULL;
   unsigned int fdecoded_options_count = 0;
+  unsigned int omp_fdecoded_options_count = 0;
   struct cl_decoded_option *decoded_options;
   unsigned int decoded_options_count;
   struct obstack argv_obstack;
@@ -629,18 +823,13 @@ run_gcc (unsigned argc, char *argv[])
   /* Look at saved options in the IL files.  */
   for (i = 1; i < argc; ++i)
     {
-      char *data, *p;
-      char *fopts;
+      char *p;
       int fd;
-      const char *errmsg;
-      int err;
-      off_t file_offset = 0, offset, length;
+      off_t file_offset = 0;
       long loffset;
-      simple_object_read *sobj;
       int consumed;
-      struct cl_decoded_option *f2decoded_options;
-      unsigned int f2decoded_options_count;
       char *filename = argv[i];
+
       if ((p = strrchr (argv[i], '@'))
 	  && p != argv[i] 
 	  && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
@@ -654,51 +843,16 @@ run_gcc (unsigned argc, char *argv[])
       fd = open (argv[i], O_RDONLY);
       if (fd == -1)
 	continue;
-      sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO", 
-	  			       &errmsg, &err);
-      if (!sobj)
-	{
-	  close (fd);
-	  continue;
-	}
-      if (!simple_object_find_section (sobj, LTO_SECTION_NAME_PREFIX "." "opts",
-				       &offset, &length, &errmsg, &err))
-	{
-	  simple_object_release_read (sobj);
-	  close (fd);
-	  continue;
-	}
-      /* We may choose not to write out this .opts section in the future.  In
-	 that case we'll have to use something else to look for.  */
-      if (simple_object_find_section (sobj, OMP_SECTION_NAME_PREFIX "." "opts",
-				      &offset, &length, &errmsg, &err))
-	have_offload = true;
-      lseek (fd, file_offset + offset, SEEK_SET);
-      data = (char *)xmalloc (length);
-      read (fd, data, length);
-      fopts = data;
-      do
-	{
-	  get_options_from_collect_gcc_options (collect_gcc,
-						fopts, CL_LANG_ALL,
-						&f2decoded_options,
-						&f2decoded_options_count);
-	  if (!fdecoded_options)
-	    {
-	      fdecoded_options = f2decoded_options;
-	      fdecoded_options_count = f2decoded_options_count;
-	    }
-	  else
-	    merge_and_complain (&fdecoded_options,
-				&fdecoded_options_count,
-				f2decoded_options, f2decoded_options_count);
-
-	  fopts += strlen (fopts) + 1;
-	}
-      while (fopts - data < length);
-
-      free (data);
-      simple_object_release_read (sobj);
+      bool omp_found;
+      find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
+			      &fdecoded_options, &fdecoded_options_count,
+			      collect_gcc);
+      omp_found = find_and_merge_options (fd, file_offset,
+					  OMP_SECTION_NAME_PREFIX,
+					  &omp_fdecoded_options,
+					  &omp_fdecoded_options_count,
+					  collect_gcc);
+      have_offload |= omp_found;
       close (fd);
     }
 
@@ -708,76 +862,21 @@ run_gcc (unsigned argc, char *argv[])
   obstack_ptr_grow (&argv_obstack, "-xlto");
   obstack_ptr_grow (&argv_obstack, "-c");
 
-  /* Append compiler driver arguments as far as they were merged.  */
-  for (j = 1; j < fdecoded_options_count; ++j)
-    {
-      struct cl_decoded_option *option = &fdecoded_options[j];
-
-      /* File options have been properly filtered by lto-opts.c.  */
-      switch (option->opt_index)
-	{
-	  /* Drop arguments that we want to take from the link line.  */
-	  case OPT_flto_:
-	  case OPT_flto:
-	  case OPT_flto_partition_:
-	      continue;
-
-	  default:
-	      break;
-	}
-
-      /* For now do what the original LTO option code was doing - pass
-	 on any CL_TARGET flag and a few selected others.  */
-      switch (option->opt_index)
-	{
-	case OPT_fPIC:
-	case OPT_fpic:
-	case OPT_fPIE:
-	case OPT_fpie:
-	case OPT_fcommon:
-	case OPT_fexceptions:
-	case OPT_fnon_call_exceptions:
-	case OPT_fgnu_tm:
-	case OPT_freg_struct_return:
-	case OPT_fpcc_struct_return:
-	case OPT_fshort_double:
-	case OPT_ffp_contract_:
-	case OPT_fwrapv:
-	case OPT_ftrapv:
-	case OPT_fstrict_overflow:
-	case OPT_O:
-	case OPT_Ofast:
-	case OPT_Og:
-	case OPT_Os:
-	  break;
-
-	default:
-	  if (!(cl_options[option->opt_index].flags & CL_TARGET))
-	    continue;
-	}
+  append_compiler_options (&argv_obstack, fdecoded_options,
+			   fdecoded_options_count);
+  append_linker_options (&argv_obstack, decoded_options, decoded_options_count,
+		      true);
 
-      /* Pass the option on.  */
-      for (i = 0; i < option->canonical_option_num_elements; ++i)
-	obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
-    }
-
-  /* Append linker driver arguments.  Compiler options from the linker
-     driver arguments will override / merge with those from the compiler.  */
+  /* Scan linker driver arguments for things that are of relevance to us.  */
   for (j = 1; j < decoded_options_count; ++j)
     {
       struct cl_decoded_option *option = &decoded_options[j];
 
-      /* Do not pass on frontend specific flags not suitable for lto.  */
-      if (!(cl_options[option->opt_index].flags
-	    & (CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO)))
-	continue;
-
       switch (option->opt_index)
 	{
 	case OPT_o:
 	  linker_output = option->arg;
-	  /* We generate new intermediate output, drop this arg.  */
-	  continue;
+	  break;
 
 	case OPT_save_temps:
 	  debug = 1;
@@ -808,23 +907,11 @@ run_gcc (unsigned argc, char *argv[])
 
 	case OPT_flto:
 	  lto_mode = LTO_MODE_WHOPR;
-	  /* We've handled these LTO options, do not pass them on.  */
-	  continue;
-
-	case OPT_freg_struct_return:
-	case OPT_fpcc_struct_return:
-	case OPT_fshort_double:
-	  /* Ignore these, they are determined by the input files.
-	     ???  We fail to diagnose a possible mismatch here.  */
-	  continue;
+	  break;
 
 	default:
 	  break;
 	}
-
-      /* Pass the option on.  */
-      for (i = 0; i < option->canonical_option_num_elements; ++i)
-	obstack_ptr_grow (&argv_obstack, option->canonical_option[i]);
     }
 
   if (no_partition)
@@ -897,7 +984,7 @@ run_gcc (unsigned argc, char *argv[])
       else
 	ltrans_output_file = make_temp_file (".ltrans.out");
       list_option_full = (char *) xmalloc (sizeof (char) *
-		         (strlen (ltrans_output_file) + list_option_len + 1));
+					   (strlen (ltrans_output_file) + list_option_len + 1));
       tmp = list_option_full;
 
       obstack_ptr_grow (&argv_obstack, tmp);
@@ -952,7 +1039,7 @@ run_gcc (unsigned argc, char *argv[])
 	  size_t len;
 
 	  buf = input_name;
-cont:
+	cont:
 	  if (!fgets (buf, piece, stream))
 	    break;
 	  len = strlen (input_name);
@@ -1003,8 +1090,8 @@ cont:
 	  if (linker_output)
 	    {
 	      char *dumpbase
-		  = (char *) xmalloc (strlen (linker_output)
-				      + sizeof (DUMPBASE_SUFFIX) + 1);
+		= (char *) xmalloc (strlen (linker_output)
+				    + sizeof (DUMPBASE_SUFFIX) + 1);
 	      snprintf (dumpbase,
 			strlen (linker_output) + sizeof (DUMPBASE_SUFFIX),
 			"%s.ltrans%u", linker_output, i);
@@ -1079,7 +1166,10 @@ cont:
 	}
       if (have_offload)
 	{
-	  compile_images_for_openmp_targets (argc, argv);
+	  compile_images_for_openmp_targets (argc, argv, omp_fdecoded_options,
+					     omp_fdecoded_options_count,
+					     decoded_options,
+					     decoded_options_count);
 	  if (offload_names)
 	    {
 	      find_ompbeginend ();
Index: gcc/target.def
===================================================================
--- gcc/target.def.orig
+++ gcc/target.def
@@ -1795,6 +1795,15 @@ actions then, you should have @code{TARG
  void, (void),
  hook_void_void)
 
+DEFHOOK
+(offload_options,
+ "Used when writing out the list of options into an LTO file.  It should\n\
+translate any relevant target-specific options (such as the ABI in use)\n\
+into one of the @option{-foffload} options that exist as a common interface\n\
+to express such options. It should return a string containing these options,\n\
+separated by spaces, which the caller will free.\n",
+char *, (void), hook_charptr_void_null)
+
 DEFHOOK_UNDOC
 (eh_return_filter_mode,
  "Return machine mode for filter value.",

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]