===================================================================
@@ -67,6 +67,7 @@ static unsigned int nr;
static char **input_names;
static char **output_names;
static char **offload_names;
+static const char *ompbegin, *ompend;
static char *makefile;
const char tool_name[] = "lto-wrapper";
@@ -479,6 +480,61 @@ compile_images_for_openmp_targets (unsig
free_array_of_ptrs ((void**) names, num_targets);
}
+/* Copy a file from SRC to DEST. */
+static void
+copy_file (const char *dest, const char *src)
+{
+ FILE *d = fopen (dest, "wb");
+ FILE *s = fopen (src, "rb");
+ char buffer[512];
+ while (!feof (s))
+ {
+ size_t len = fread (buffer, 1, 512, s);
+ if (ferror (s) != 0)
+ fatal ("reading input file");
+ if (len > 0)
+ {
+ fwrite (buffer, 1, len, d);
+ if (ferror (d) != 0)
+ fatal ("writing output file");
+ }
+ }
+}
+
+/* Find the omp_begin.o and omp_end.o files in LIBRARY_PATH, make copies
+ and store the names of the copies in ompbegin and ompend. */
+
+static void
+find_ompbeginend (void)
+{
+ char **paths;
+ const char *library_path = getenv ("LIBRARY_PATH");
+ if (library_path == NULL)
+ return;
+ int n_paths = parse_env_var (library_path, &paths, "/ompbegin.o");
+
+ for (int i = 0; i < n_paths; i++)
+ if (access_check (paths[i], R_OK) == 0)
+ {
+ size_t len = strlen (paths[i]);
+ char *tmp = xstrdup (paths[i]);
+ strcpy (paths[i] + len - 7, "end.o");
+ if (access_check (paths[i], R_OK) != 0)
+ fatal ("installation error, can't find ompend.o");
+ /* The linker will delete the filenames we give it, so make
+ copies. */
+ const char *omptmp1 = make_temp_file (".o");
+ const char *omptmp2 = make_temp_file (".o");
+ copy_file (omptmp1, tmp);
+ ompbegin = omptmp1;
+ copy_file (omptmp2, paths[i]);
+ ompend = oindmptmp2;
+ free (tmp);
+ break;
+ }
+
+ free_array_of_ptrs ((void**) paths, n_paths);
+}
/* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
@@ -964,6 +1020,7 @@ cont:
compile_images_for_openmp_targets (argc, argv);
if (offload_names)
{
+ find_ompbeginend ();
for (i = 0; offload_names[i]; i++)
{
fputs (offload_names[i], stdout);
@@ -972,12 +1029,23 @@ cont:
free_array_of_ptrs ((void **)offload_names, i);
}
}
+ if (ompbegin)
+ {
+ fputs (ompbegin, stdout);
+ putc ('\n', stdout);
+ }
+
for (i = 0; i < nr; ++i)
{
fputs (output_names[i], stdout);
putc ('\n', stdout);
free (input_names[i]);
}
+ if (ompend)
+ {
+ fputs (ompend, stdout);
+ putc ('\n', stdout);
+ }
nr = 0;
free (output_names);
free (input_names);
===================================================================
@@ -566,6 +566,7 @@ sfp_machine_header
set_use_emutls
set_have_cc_tls
vis_hide
+enable_accelerator
fixed_point
enable_decimal_float
decimal_float
@@ -664,6 +665,8 @@ with_build_libsubdir
enable_decimal_float
with_system_libunwind
enable_sjlj_exceptions
+enable_accelerator
+enable_offload_targets
enable_tls
'
ac_precious_vars='build_alias
@@ -1301,6 +1304,9 @@ Optional Features:
to use
--enable-sjlj-exceptions
force use of builtin_setjmp for exceptions
+ --enable-accelerator build accelerator [ARG={no,device-triplet}]
+ --enable-offload-targets=LIST
+ enable offloading to devices from LIST
--enable-tls Use thread-local storage [default=yes]
Optional Packages:
@@ -4357,6 +4363,43 @@ esac
# Collect host-machine-specific information.
. ${srcdir}/config.host
+offload_targets=
+# Check whether --enable-accelerator was given.
+if test "${enable_accelerator+set}" = set; then :
+ enableval=$enable_accelerator;
+ case $enable_accelerator in
+ no) ;;
+ *)
+ offload_targets=$enable_accelerator
+ ;;
+ esac
+
+fi
+
+
+
+# Check whether --enable-offload-targets was given.
+if test "${enable_offload_targets+set}" = set; then :
+ enableval=$enable_offload_targets;
+ if test x$enable_offload_targets = x; then
+ as_fn_error "no offload targets specified" "$LINENO" 5
+ else
+ if test x$offload_targets = x; then
+ offload_targets=$enable_offload_targets
+ else
+ offload_targets=$offload_targets,$enable_offload_targets
+ fi
+ fi
+
+else
+ enable_accelerator=no
+fi
+
+
+if test x$offload_targets != x; then
+ extra_parts="${extra_parts} ompbegin.o ompend.o"
+fi
+
# Check if Solaris/x86 linker supports ZERO terminator unwind entries.
# This is after config.host so we can augment tmake_file.
# Link with -nostartfiles -nodefaultlibs since neither are present while
===================================================================
@@ -307,6 +307,38 @@ esac
# Collect host-machine-specific information.
. ${srcdir}/config.host
+offload_targets=
+AC_ARG_ENABLE(accelerator,
+[AS_HELP_STRING([--enable-accelerator], [build accelerator @<:@ARG={no,device-triplet}@:>@])],
+[
+ case $enable_accelerator in
+ no) ;;
+ *)
+ offload_targets=$enable_accelerator
+ ;;
+ esac
+], [])
+AC_SUBST(enable_accelerator)
+
+AC_ARG_ENABLE(offload-targets,
+[AS_HELP_STRING([--enable-offload-targets=LIST],
+ [enable offloading to devices from LIST])],
+[
+ if test x$enable_offload_targets = x; then
+ AC_MSG_ERROR([no offload targets specified])
+ else
+ if test x$offload_targets = x; then
+ offload_targets=$enable_offload_targets
+ else
+ offload_targets=$offload_targets,$enable_offload_targets
+ fi
+ fi
+], [enable_accelerator=no])
+AC_SUBST(enable_accelerator)
+if test x$offload_targets != x; then
+ extra_parts="${extra_parts} ompbegin.o ompend.o"
+fi
+
# Check if Solaris/x86 linker supports ZERO terminator unwind entries.
# This is after config.host so we can augment tmake_file.
# Link with -nostartfiles -nodefaultlibs since neither are present while
===================================================================
@@ -311,15 +311,6 @@ register_tm_clones (void)
}
#endif /* USE_TM_CLONE_REGISTRY */
-#if defined(HAVE_GAS_HIDDEN) && defined(ENABLE_OFFLOADING)
-void *_omp_func_table[0]
- __attribute__ ((__used__, visibility ("protected"),
- section (".offload_func_table_section"))) = { };
-void *_omp_var_table[0]
- __attribute__ ((__used__, visibility ("protected"),
- section (".offload_var_table_section"))) = { };
-#endif
-
#if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP)
#ifdef OBJECT_FORMAT_ELF
@@ -761,22 +752,6 @@ __do_global_ctors (void)
#error "What are you doing with crtstuff.c, then?"
#endif
-#if defined(HAVE_GAS_HIDDEN) && defined(ENABLE_OFFLOADING)
-void *_omp_funcs_end[0]
- __attribute__ ((__used__, visibility ("protected"),
- section (".offload_func_table_section"))) = { };
-void *_omp_vars_end[0]
- __attribute__ ((__used__, visibility ("protected"),
- section (".offload_var_table_section"))) = { };
-extern void *_omp_func_table[];
-extern void *_omp_var_table[];
-void *__OPENMP_TARGET__[] __attribute__ ((__visibility__ ("protected"))) =
-{
- &_omp_func_table, &_omp_funcs_end,
- &_omp_var_table, &_omp_vars_end
-};
-#endif
-
#else /* ! CRT_BEGIN && ! CRT_END */
#error "One of CRT_BEGIN or CRT_END must be defined."
===================================================================
@@ -975,6 +975,12 @@ crtbegin$(objext): $(srcdir)/crtstuff.c
crtend$(objext): $(srcdir)/crtstuff.c
$(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_END
+ompbegin$(objext): $(srcdir)/ompstuff.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_BEGIN
+
+ompend$(objext): $(srcdir)/ompstuff.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_END
+
# These are versions of crtbegin and crtend for shared libraries.
crtbeginS$(objext): $(srcdir)/crtstuff.c
$(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $< -DCRT_BEGIN -DCRTSTUFFS_O
===================================================================
@@ -0,0 +1,73 @@
+/* Specialized bits of code needed for the OpenMP offloading tables.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Target machine header files require this define. */
+#define IN_LIBGCC2
+
+/* FIXME: Including auto-host is incorrect, but until we have
+ identified the set of defines that need to go into auto-target.h,
+ this will have to do. */
+#include "auto-host.h"
+#undef pid_t
+#undef rlim_t
+#undef ssize_t
+#undef vfork
+#include "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "libgcc_tm.h"
+
+#ifdef CRT_BEGIN
+
+#if defined(HAVE_GAS_HIDDEN) && defined(ENABLE_OFFLOADING)
+void *_omp_func_table[0]
+ __attribute__ ((__used__, visibility ("protected"),
+ section (".offload_func_table_section"))) = { };
+void *_omp_var_table[0]
+ __attribute__ ((__used__, visibility ("protected"),
+ section (".offload_var_table_section"))) = { };
+#endif
+
+#elif defined CRT_END
+
+#if defined(HAVE_GAS_HIDDEN) && defined(ENABLE_OFFLOADING)
+void *_omp_funcs_end[0]
+ __attribute__ ((__used__, visibility ("protected"),
+ section (".offload_func_table_section"))) = { };
+void *_omp_vars_end[0]
+ __attribute__ ((__used__, visibility ("protected"),
+ section (".offload_var_table_section"))) = { };
+extern void *_omp_func_table[];
+extern void *_omp_var_table[];
+void *__OPENMP_TARGET__[] __attribute__ ((__visibility__ ("protected"))) =
+{
+ &_omp_func_table, &_omp_funcs_end,
+ &_omp_var_table, &_omp_vars_end
+};
+#endif
+
+#else /* ! CRT_BEGIN && ! CRT_END */
+#error "One of CRT_BEGIN or CRT_END must be defined."
+#endif