===================================================================
@@ -1016,16 +1016,20 @@ proper position among the other output f
%{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
"%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
"%X %{o*} %{e*} %{N} %{n} %{r}\
- %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \
+ %{s} %{t} %{u*} %{z} %{Z}\
+ %{!nostdlib:%{!nostartfiles:%{fupc:%:include(upc-crtbegin.spec)%(upc_crtbegin)}}}\
+ %{!nostdlib:%{!nostartfiles:%S}} \
%{static:} %{L*} %(mfwrap) %(link_libgcc) " \
VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o " CHKP_SPEC " \
%{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*} 1):\
%:include(libgomp.spec)%(link_gomp)}\
%{fcilkplus:%:include(libcilkrts.spec)%(link_cilkrts)}\
%{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
+ %{fupc:%:include(libgupc.spec)%(link_upc)}\
%(mflib) " STACK_SPLIT_SPEC "\
%{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
%{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
+ %{!nostdlib:%{!nostartfiles:%{fupc:%:include(upc-crtend.spec)%(upc_crtend)}}}\
%{!nostdlib:%{!nostartfiles:%E}} %{T*} \n%(post_link) }}}}}}"
#endif
@@ -1061,6 +1065,9 @@ static const char *asm_final_spec = ASM_
static const char *link_spec = LINK_SPEC;
static const char *lib_spec = LIB_SPEC;
static const char *link_gomp_spec = "";
+static const char *upc_crtbegin_spec = "";
+static const char *link_upc_spec = "";
+static const char *upc_crtend_spec = "";
static const char *libgcc_spec = LIBGCC_SPEC;
static const char *endfile_spec = ENDFILE_SPEC;
static const char *startfile_spec = STARTFILE_SPEC;
@@ -1134,6 +1141,9 @@ static const char *cc1_options =
%{fsyntax-only:-o %j} %{-param*}\
%{coverage:-fprofile-arcs -ftest-coverage}";
+static const char *upc_options =
+ "-fupc %{!fno-upc-pre-include:-include gcc-upc.h}";
+
static const char *asm_options =
"%{-target-help:%:print-asm-header()} "
#if HAVE_GNU_AS
@@ -1345,6 +1355,21 @@ static const struct compiler default_com
as %(asm_debug) %(asm_options) %m.s %A }}}}"
#endif
, 0, 0, 0},
+ {".upc", "@upc", 0, 0, 0},
+ {"@upc",
+ /* Same as "@c" above, with the addition of %(upc_options). */
+ "%{E|M|MM:cc1 -E %(upc_options) %(cpp_options) %(cpp_debug_options)}\
+ %{!E:%{!M:%{!MM:\
+ %{traditional|ftraditional|traditional-cpp:\
+ %e UPC does not support traditional compilation}\
+ %{save-temps|no-integrated-cpp:\
+ cc1 -E %(upc_options) %(cpp_options)\
+ %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\
+ cc1 -fpreprocessed %{save-temps:%b.mi} %{!save-temps:%g.mi}\
+ %(upc_options) %(cc1_options)}\
+ %{!save-temps:%{!no-integrated-cpp:\
+ cc1 %(cpp_unique_options) %(upc_options) %(cc1_options)}}\
+ %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
#include "specs.h"
/* Mark end of table. */
@@ -1555,6 +1580,7 @@ static struct spec_list static_specs[] =
INIT_STATIC_SPEC ("trad_capable_cpp", &trad_capable_cpp),
INIT_STATIC_SPEC ("cc1", &cc1_spec),
INIT_STATIC_SPEC ("cc1_options", &cc1_options),
+ INIT_STATIC_SPEC ("upc_options", &upc_options),
INIT_STATIC_SPEC ("cc1plus", &cc1plus_spec),
INIT_STATIC_SPEC ("link_gcc_c_sequence", &link_gcc_c_sequence_spec),
INIT_STATIC_SPEC ("link_ssp", &link_ssp_spec),
@@ -1562,6 +1588,9 @@ static struct spec_list static_specs[] =
INIT_STATIC_SPEC ("link", &link_spec),
INIT_STATIC_SPEC ("lib", &lib_spec),
INIT_STATIC_SPEC ("link_gomp", &link_gomp_spec),
+ INIT_STATIC_SPEC ("upc_crtbegin", &upc_crtbegin_spec),
+ INIT_STATIC_SPEC ("link_upc", &link_upc_spec),
+ INIT_STATIC_SPEC ("upc_crtend", &upc_crtend_spec),
INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
INIT_STATIC_SPEC ("startfile", &startfile_spec),
INIT_STATIC_SPEC ("cross_compile", &cross_compile),
===================================================================
@@ -143,6 +143,7 @@ DEFTIMEVAR (TV_EARLY_INLINING , "
DEFTIMEVAR (TV_INLINE_PARAMETERS , "inline parameters")
DEFTIMEVAR (TV_INTEGRATION , "integration")
DEFTIMEVAR (TV_TREE_GIMPLIFY , "tree gimplify")
+DEFTIMEVAR (TV_TREE_UPC_GENERICIZE , "tree UPC genericize")
DEFTIMEVAR (TV_TREE_EH , "tree eh")
DEFTIMEVAR (TV_TREE_CFG , "tree CFG construction")
DEFTIMEVAR (TV_TREE_CLEANUP_CFG , "tree CFG cleanup")
===================================================================
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.
#include "tm_p.h" /* For C_COMMON_OVERRIDE_OPTIONS. */
#include "diagnostic.h"
#include "c-pragma.h"
+#include "c-upc-pts.h"
#include "flags.h"
#include "toplev.h"
#include "langhooks.h"
@@ -208,6 +209,46 @@ c_common_init_options_struct (struct gcc
opts->x_flag_complex_method = 2;
}
+/* Initialize UPC-specific options. */
+static void
+upc_init_options ()
+{
+ struct cl_option_handlers handlers;
+
+ /* UPC is based upon the C99 dialect. Assert it here.
+ * We'll let the user override these options as he/she
+ * sees fit. For example, -traditional will disable
+ * prototype checking. */
+ set_std_c99 ( 0 /* iso=0 */ );
+
+ /* The consensus of the UPC community seems to be that
+ arithmetic on (void *) pointers and sizeof (void)
+ are compilation errors. Enable this warning-as-error
+ mode by default. */
+ warn_pointer_arith = 1;
+ set_default_handlers (&handlers);
+ control_warning_option (OPT_Wpointer_arith, (int) DK_ERROR, true,
+ UNKNOWN_LOCATION, CL_C,
+ &handlers, &global_options, &global_options_set,
+ global_dc);
+
+ /* By default, don't generate UPC's DWARF2 extensions. */
+ use_upc_dwarf2_extensions = 0;
+ flag_upc = 1;
+ flag_upc_threads = 0;
+ flag_upc_pthreads = 0;
+ /* By default, don't map UPC threads to POSIX threads. */
+ flag_upc_pthreads = 0;
+ upc_pthreads_model = upc_pthreads_no_model;
+ /* By default, GASP profiling is off. */
+ flag_upc_instrument = 0;
+ flag_upc_instrument_functions = 0;
+ /* By default, optimization level > 0 defines shared access routines
+ inlining, otherwise use the user specified flag to unconditionally
+ enable/disable inlining of the UPC shared memory access routines. */
+ flag_upc_inline_lib = -1;
+}
+
/* Common initialization before calling option handlers. */
void
c_common_init_options (unsigned int decoded_options_count,
@@ -235,20 +276,94 @@ c_common_init_options (unsigned int deco
{
/* The default for C is gnu11. */
set_std_c11 (false /* ISO */);
-
- /* If preprocessing assembly language, accept any of the C-family
- front end options since the driver may pass them through. */
for (i = 1; i < decoded_options_count; i++)
- if (decoded_options[i].opt_index == OPT_lang_asm)
- {
- accept_all_c_family_options = true;
- break;
- }
+ {
+ /* If preprocessing assembly language, accept any of the C-family
+ front end options since the driver may pass them through. */
+ if (decoded_options[i].opt_index == OPT_lang_asm)
+ {
+ accept_all_c_family_options = true;
+ break;
+ }
+ /* If compiling UPC, initialize appropriate default options. */
+ if (decoded_options[i].opt_index == OPT_fupc)
+ {
+ upc_init_options ();
+ break;
+ }
+ }
}
global_dc->colorize_source_p = true;
}
+/* Process UPC specific command line switches */
+
+static bool
+upc_handle_option (const enum opt_code code, const char *arg, const int value)
+{
+ int result = 1;
+ if (!flag_upc)
+ {
+ error ("%s is supported only when -fupc is also present", arg);
+ return false;
+ }
+ switch (code)
+ {
+ default:
+ gcc_unreachable ();
+ break;
+ case OPT_fupc:
+ flag_upc = value;
+ break;
+ case OPT_dwarf_2_upc:
+ use_upc_dwarf2_extensions = value;
+ break;
+ case OPT_fupc_debug:
+ if ((value == 1) && (flag_upc_inline_lib == 1))
+ error ("-fupc-debug is incompatible with -fupc-inline-lib");
+ flag_upc_debug = value;
+ break;
+ case OPT_fupc_inline_lib:
+ if ((value == 1) && (flag_upc_instrument == 1))
+ error ("-fupc-inline-lib is incompatible with -fupc-instrument");
+ if ((value == 1) && (flag_upc_debug == 1))
+ error ("-fupc-inline-lib is incompatible with -fupc-debug");
+ flag_upc_inline_lib = value;
+ break;
+ case OPT_fupc_instrument:
+ if ((value == 1) && (flag_upc_inline_lib == 1))
+ error ("-fupc-instrument is incompatible with -fupc-inline-lib");
+ flag_upc_instrument = value;
+ break;
+ case OPT_fupc_instrument_functions:
+ if ((value == 1) && (flag_upc_inline_lib == 1))
+ error
+ ("-fupc-instrument-functions is incompatible "
+ "with -fupc-inline-lib");
+ flag_upc_instrument = value;
+ flag_upc_instrument_functions = value;
+ break;
+ case OPT_fupc_pthreads_model_tls:
+ flag_upc_pthreads = 1;
+ upc_pthreads_model = upc_pthreads_tls_model;
+ break;
+ case OPT_fupc_threads_:
+ {
+ int num_threads = value;
+ if (num_threads > UPC_MAX_THREADS)
+ {
+ error ("THREADS value exceeds UPC implementation limit of %d",
+ UPC_MAX_THREADS);
+ num_threads = 1;
+ }
+ flag_upc_threads = num_threads;
+ }
+ break;
+ }
+ return result;
+}
+
/* Handle switch SCODE with argument ARG. VALUE is true, unless no-
form of an -f or -W option was given. Returns false if the switch was
invalid, true if valid. Use HANDLERS in recursive handle_option calls. */
@@ -532,6 +647,17 @@ c_common_handle_option (size_t scode, co
cpp_opts->ext_numeric_literals = value;
break;
+ case OPT_fupc:
+ case OPT_dwarf_2_upc:
+ case OPT_fupc_debug:
+ case OPT_fupc_inline_lib:
+ case OPT_fupc_instrument:
+ case OPT_fupc_instrument_functions:
+ case OPT_fupc_pthreads_model_tls:
+ case OPT_fupc_threads_:
+ result = upc_handle_option (code, arg, value);
+ break;
+
case OPT_idirafter:
add_path (xstrdup (arg), AFTER, 0, true);
break;
@@ -1062,6 +1188,9 @@ c_common_parse_file (void)
pch_init ();
push_file_scope ();
c_parse_file ();
+ /* Generate UPC global initialization code, if required. */
+ if (flag_upc)
+ (*lang_hooks.upc.write_global_declarations) ();
pop_file_scope ();
/* And end the main input file, if the debug writer wants it */
if (debug_hooks->start_end_main_source_file)
===================================================================
@@ -992,6 +992,10 @@ d
C ObjC C++ ObjC++ Joined
; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD?
+dwarf-2-upc
+C Report Var(use_upc_dwarf2_extensions) Init(0)
+Generate DWARF-2 debug info with UPC extensions.
+
fabi-compat-version=
C++ ObjC++ Joined RejectNegative UInteger Var(flag_abi_compat_version) Init(-1)
The version of the C++ ABI used for -Wabi warnings and link compatibility aliases.
@@ -1512,6 +1516,46 @@ funsigned-char
C ObjC C++ ObjC++ LTO Var(flag_signed_char, 0)
Make \"char\" unsigned by default.
+fupc
+C Report Var(flag_upc) Init(0)
+Enable UPC.
+
+fupc-debug
+C Var(flag_upc_debug)
+Generate code that provides the UPC runtime with
+the file and line number where the runtime was called.
+
+fupc-inline-lib
+C Var(flag_upc_inline_lib)
+Generate code for inlined UPC runtime library routines.
+Default, at optimization levels greater than 0.
+
+fupc-pre-include
+C Init(1)
+Pre-include UPC runtime header file.
+
+fupc-pthreads-model-tls
+C
+Generate code for a POSIX threads based UPC runtime environment
+with TLS (Thread Local Storage) support.
+
+fupc-threads=
+C Joined RejectNegative UInteger
+Specify the compile-time value of THREADS.
+
+fupc-threads-
+C Joined RejectNegative UInteger Alias(fupc-threads=)
+Deprecated in favor of -fupc-threads=.
+
+fupc-instrument
+C Var(flag_upc_instrument)
+Instrument UPC shared accesses and library calls, using GASP tool support.
+
+fupc-instrument-functions
+C Var(flag_upc_instrument_functions)
+Instrument functions calls, using GASP tool support
+(implies -fupc-instrument).
+
fuse-cxa-atexit
C++ ObjC++ Var(flag_use_cxa_atexit) Init(DEFAULT_USE_CXA_ATEXIT)
Use __cxa_atexit to register destructors.
===================================================================
@@ -0,0 +1,303 @@
+/* gupcspec.c: the UPC compiler driver program
+ Copyright (C) 2001-2015 Free Software Foundation, Inc.
+ Contributed by Gary Funck <gary@intrepid.com>
+ and Nenad Vukicevic <nenad@intrepid.com>.
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "gcc.h"
+#include "opts.h"
+
+#include "tm.h"
+
+
+/* GUPC driver - derived from fortran/gfortranspec.c. */
+
+/* The original argument list and related info is copied here. */
+static unsigned int gupc_xargc;
+static const struct cl_decoded_option *gupc_x_decoded_options;
+static void append_arg (const struct cl_decoded_option *);
+
+/* The new argument list will be built here. */
+static unsigned int gupc_newargc;
+static struct cl_decoded_option *gupc_new_decoded_options;
+
+static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
+static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
+
+/* By default the linker is always invoked. */
+static int invoke_linker = 1;
+
+static int match_suffix (const char *s, const char *suffix);
+
+#define END_ARGS ((char *) 0)
+
+/* Return true if the strings S1 and S2 are either both NULL
+ * or both the same string. */
+
+static bool
+strings_same (const char *s1, const char *s2)
+{
+ return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
+}
+
+/* Return whether decoded option structures OPT1 and OPT2 are the
+ same. */
+
+static bool
+options_same (const struct cl_decoded_option *opt1,
+ const struct cl_decoded_option *opt2)
+{
+ return (opt1->opt_index == opt2->opt_index
+ && strings_same (opt1->arg, opt2->arg)
+ && strings_same (opt1->orig_option_with_args_text,
+ opt2->orig_option_with_args_text)
+ && strings_same (opt1->canonical_option[0],
+ opt2->canonical_option[0])
+ && strings_same (opt1->canonical_option[1],
+ opt2->canonical_option[1])
+ && strings_same (opt1->canonical_option[2],
+ opt2->canonical_option[2])
+ && strings_same (opt1->canonical_option[3],
+ opt2->canonical_option[3])
+ && (opt1->canonical_option_num_elements
+ == opt2->canonical_option_num_elements)
+ && opt1->value == opt2->value && opt1->errors == opt2->errors);
+}
+
+/* Append another argument to the list being built. As long as it is
+ identical to the corresponding arg in the original list, just increment
+ the new arg count. Otherwise allocate a new list, etc. */
+
+static void
+append_arg (const struct cl_decoded_option *arg)
+{
+ static unsigned int newargsize;
+
+ if (gupc_new_decoded_options == gupc_x_decoded_options
+ && gupc_newargc < gupc_xargc
+ && options_same (arg, &gupc_x_decoded_options[gupc_newargc]))
+ {
+ ++gupc_newargc;
+ return; /* Nothing new here. */
+ }
+
+ if (gupc_new_decoded_options == gupc_x_decoded_options)
+ { /* Make new arglist. */
+ unsigned int i;
+
+ newargsize = (gupc_xargc << 2) + 20; /* This should handle all. */
+ gupc_new_decoded_options =
+ XNEWVEC (struct cl_decoded_option, newargsize);
+
+ /* Copy what has been done so far. */
+ for (i = 0; i < gupc_newargc; ++i)
+ gupc_new_decoded_options[i] = gupc_x_decoded_options[i];
+ }
+
+ if (gupc_newargc == newargsize)
+ fatal_error (input_location, "overflowed output arg list for %qs",
+ arg->orig_option_with_args_text);
+
+ gupc_new_decoded_options[gupc_newargc++] = *arg;
+}
+
+/* Append an option described by OPT_INDEX, ARG and VALUE to the list
+ being built. */
+static void
+append_option (size_t opt_index, const char *arg, int value)
+{
+ struct cl_decoded_option decoded;
+
+ generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
+ append_arg (&decoded);
+}
+
+static int
+match_suffix (const char *s, const char *suffix)
+{
+ int slen = strlen (s);
+ int xlen = strlen (suffix);
+ const char *start = (xlen <= slen) ? s + slen - xlen : 0;
+ return start && !strncmp (start, suffix, xlen);
+}
+
+void
+lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+ unsigned int *in_decoded_options_count,
+ int *in_added_libraries ATTRIBUTE_UNUSED)
+{
+ struct cl_decoded_option *decoded_options = *in_decoded_options;
+ unsigned int i;
+ int is_x_in_effect = 0;
+ int is_x_upc_in_effect = 0;
+ int verbose = 0;
+ int n_infiles = 0;
+ int n_outfiles = 0;
+ int pre_processed = 0;
+
+ gupc_xargc = *in_decoded_options_count;
+ gupc_x_decoded_options = decoded_options;
+ gupc_newargc = 0;
+ gupc_new_decoded_options = decoded_options;
+
+ /* First pass through the argument list. */
+
+ /* Check to see if any switches are asserted that inhibit linking
+ and record the presence of other switches that may require
+ special handling. */
+ for (i = 1; i < gupc_xargc; ++i)
+ {
+ if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
+ continue;
+
+ switch (decoded_options[i].opt_index)
+ {
+
+ case OPT_SPECIAL_input_file:
+ ++n_infiles;
+ continue;
+
+ case OPT_nostdlib:
+ case OPT_nodefaultlibs:
+ case OPT_c:
+ case OPT_S:
+ case OPT_fsyntax_only:
+ case OPT_E:
+ /* These options disable linking entirely or linking of the
+ standard libraries. */
+ invoke_linker = 0;
+ break;
+
+ case OPT_fpreprocessed:
+ pre_processed = 1;
+ break;
+
+ case OPT_l:
+ ++n_infiles;
+ break;
+
+ case OPT_o:
+ ++n_outfiles;
+ break;
+
+ case OPT_v:
+ verbose = 1;
+ break;
+
+ case OPT__version:
+ /* Optional GUPC version string. Let GCC handle it for now. */
+ break;
+
+ case OPT__help:
+ /* Let gcc.c handle this, as it has a really
+ cool facility for handling --help and --verbose --help. */
+ return;
+
+ default:
+ break;
+ }
+ }
+
+ /* Create the new argument list. */
+
+ /* Start with the compiler itself. */
+ append_arg (&decoded_options[0]);
+
+ /* Always assert -fupc. */
+ append_option (OPT_fupc, NULL, 1);
+
+ /* If there are no input files, no need for the library. */
+ if (n_infiles == 0)
+ invoke_linker = 0;
+
+ /* Copy in the arguments as passed to 'upc' */
+ is_x_in_effect = 0;
+ is_x_upc_in_effect = 0;
+ for (i = 1; i < gupc_xargc; ++i)
+ {
+ /* Skip -fupc, we asserted it above. */
+ if (decoded_options[i].opt_index == OPT_fupc)
+ continue;
+
+ /* Check for "-x [c,upc,..]". */
+ if (decoded_options[i].opt_index == OPT_x)
+ {
+ /* Go to default if "none" found. */
+ if (!strcmp (decoded_options[i].arg, "none"))
+ {
+ is_x_in_effect = 0;
+ is_x_upc_in_effect = 0;
+ }
+ else
+ is_x_in_effect = 1;
+ }
+
+ /* By default, driver accepts C files as UPC files. Unless there
+ is "-x" option in affect. */
+ if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
+ {
+ const int is_c_file = match_suffix (decoded_options[i].arg, ".c")
+ || match_suffix (decoded_options[i].arg, ".h")
+ || (pre_processed && match_suffix (decoded_options[i].arg, ".i"));
+ if (is_c_file)
+ {
+ if ( !(is_x_in_effect || is_x_upc_in_effect))
+ {
+ append_option (OPT_x, "upc", 1);
+ is_x_upc_in_effect = 1;
+ }
+ append_arg (&decoded_options[i]);
+ continue;
+ }
+ else
+ {
+ if (is_x_upc_in_effect)
+ {
+ is_x_upc_in_effect = 0;
+ append_option (OPT_x, "none", 1);
+ }
+ }
+ }
+ append_arg (&decoded_options[i]);
+ }
+
+ if (verbose)
+ {
+ fprintf (stderr, "Driving:");
+ for (i = 0; i < gupc_newargc; i++)
+ fprintf (stderr, " %s",
+ gupc_new_decoded_options[i].orig_option_with_args_text);
+ fprintf (stderr, "\n");
+ }
+
+ *in_decoded_options_count = gupc_newargc;
+ *in_decoded_options = gupc_new_decoded_options;
+}
+
+/* Called before linking. Returns 0 on success and -1 on failure. */
+int
+lang_specific_pre_link (void)
+{
+ return 0;
+}
+
+/* Number of extra output files that lang_specific_pre_link may generate. */
+int lang_specific_extra_outfiles = 0; /* Not used for GUPC. */