diff mbox

[3/4] "Output targets", DECL_TARGET, and lto output

Message ID 52988A83.1090403@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt Nov. 29, 2013, 12:37 p.m. UTC
This is the largest patch (can be split up more, but I wanted to get
this out the door).

It adds the list of "output targets" which I hope someone will find a
better name for, the corresponding DECL_TARGET, and mechanisms to write
out lto for multiple targets. Also moves LTO section names into a
separate header as already suggested by existing comments. It also adds
"--enable-as-accelerator_for=" and Makefile.in bits for installing into
different paths than the usual ones.

This part requires reverting the current offload patch first.


Bernd
diff mbox

Patch

Index: Makefile.def
===================================================================
--- Makefile.def.orig
+++ Makefile.def
@@ -45,7 +45,9 @@  host_modules= { module= flex; no_check_c
 host_modules= { module= gas; bootstrap=true; };
 host_modules= { module= gcc; bootstrap=true; 
 		extra_make_flags="$(EXTRA_GCC_FLAGS)"; };
-host_modules= { module= accel-gcc; actual_module=gcc; };
+host_modules= { module= accel-gcc;
+	        actual_module=gcc;
+		extra_configure_flags='--enable-as-accelerator-for=$(target_alias)'; };
 host_modules= { module= gmp; lib_path=.libs; bootstrap=true;
 		extra_configure_flags='--disable-shared';
 		no_install= true;
Index: Makefile.in
===================================================================
--- Makefile.in.orig
+++ Makefile.in
@@ -10516,7 +10516,7 @@  configure-accel-gcc:
 	libsrcdir="$$s/gcc"; \
 	$(SHELL) $${libsrcdir}/configure \
 	  $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
-	  --target=$${this_target} $${srcdiroption}  \
+	  --target=$${this_target} $${srcdiroption} --enable-as-accelerator-for=$(target_alias) \
 	  || exit 1
 @endif accel-gcc
 
Index: gcc/cgraphunit.c
===================================================================
--- gcc/cgraphunit.c.orig
+++ gcc/cgraphunit.c
@@ -2140,9 +2140,7 @@  compile (void)
     fprintf (stderr, "Performing interprocedural optimizations\n");
   cgraph_state = CGRAPH_STATE_IPA;
 
-  /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE.  */
-  if (flag_lto)
-    lto_streamer_hooks_init ();
+  lto_streamer_hooks_init ();
 
   /* Don't run the IPA passes if there was any error or sorry messages.  */
   if (!seen_error ())
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c.orig
+++ gcc/config/darwin.c
@@ -51,6 +51,7 @@  along with GCC; see the file COPYING3.
 #include "gimple.h"
 #include "gimplify.h"
 #include "lto-streamer.h"
+#include "lto-section-names.h"
 
 /* Darwin supports a feature called fix-and-continue, which is used
    for rapid turn around debugging.  When code is compiled with the
@@ -1890,9 +1891,6 @@  typedef struct GTY (()) darwin_lto_secti
 
 static GTY (()) vec<darwin_lto_section_e, va_gc> *lto_section_names;
 
-/* Segment for LTO data.  */
-#define LTO_SEGMENT_NAME "__GNU_LTO"
-
 /* Section wrapper scheme (used here to wrap the unlimited number of LTO
    sections into three Mach-O ones).
    NOTE: These names MUST be kept in sync with those in
Index: gcc/config/i386/winnt.c
===================================================================
--- gcc/config/i386/winnt.c.orig
+++ gcc/config/i386/winnt.c
@@ -39,6 +39,7 @@  along with GCC; see the file COPYING3.
 #include "except.h"
 #include "gimple.h"
 #include "lto-streamer.h"
+#include "lto-section-names.h"
 
 /* i386/PE specific attribute support.
 
Index: gcc/config.in
===================================================================
--- gcc/config.in.orig
+++ gcc/config.in
@@ -1,5 +1,18 @@ 
 /* config.in.  Generated from configure.ac by autoheader.  */
 
+/* Define if this compiler should be built and used as the target device
+   compiler for OpenACC. */
+#ifndef USED_FOR_TARGET
+#undef ACCEL_COMPILER
+#endif
+
+
+/* Define to the name of the OpenACC accelerator target. */
+#ifndef USED_FOR_TARGET
+#undef ACCEL_TARGET
+#endif
+
+
 /* Define if building universal (internal helper macro) */
 #ifndef USED_FOR_TARGET
 #undef AC_APPLE_UNIVERSAL_BUILD
Index: gcc/configure.ac
===================================================================
--- gcc/configure.ac.orig
+++ gcc/configure.ac
@@ -38,6 +38,11 @@  AC_CANONICAL_TARGET
 # Determine the noncanonical target name, for directory use.
 ACX_NONCANONICAL_TARGET
 
+# Used for install directories
+install_dirname=$target_noncanonical
+# Used for prefixing tool names
+tool_prefix=$target_noncanonical
+
 # Determine the target- and build-specific subdirectories
 GCC_TOPLEV_SUBDIRS
 
@@ -834,6 +839,35 @@  AC_ARG_ENABLE(languages,
 esac],
 [enable_languages=c])
 
+AC_ARG_ENABLE(accelerator,
+[AS_HELP_STRING([--enable-accelerator], [build accelerator @<:@ARG={no,device-triplet}@:>@])],
+[
+  case $enable_accelerator in
+  no) ;;
+  *)
+    AC_DEFINE_UNQUOTED(ACCEL_TARGET,"${enable_accelerator}",
+     [Define to the name of the OpenACC accelerator target.])
+    ;;
+  esac
+], [enable_accelerator=no])
+AC_SUBST(enable_accelerator)
+
+AC_ARG_ENABLE(as-accelerator-for,
+[AS_HELP_STRING([--enable-as-accelerator-for], [build compiler as accelerator target for given host])],
+[
+  if test $enable_accelerator = no; then
+    echo "--enable-as-accelerator-for requires --enable-accelerator"
+    exit 1;
+  fi
+  AC_DEFINE(ACCEL_COMPILER, 1,
+   [Define if this compiler should be built and used as the target
+    device compiler for OpenACC.])
+  enable_as_accelerator=yes
+  tool_prefix=${enable_as_accelerator_for}-accel-${enable_accelerator}
+  install_dirname=${enable_as_accelerator_for}/accel/${enable_accelerator}
+], [enable_as_accelerator=no])
+AC_SUBST(enable_as_accelerator)
+
 AC_ARG_WITH(multilib-list,
 [AS_HELP_STRING([--with-multilib-list], [select multilibs (AArch64, SH and x86-64 only)])],
 :,
@@ -5274,6 +5308,8 @@  AC_SUBST(c_target_objs)
 AC_SUBST(cxx_target_objs)
 AC_SUBST(fortran_target_objs)
 AC_SUBST(target_cpu_default)
+AC_SUBST(install_dirname)
+AC_SUBST(tool_prefix)
 
 AC_SUBST_FILE(language_hooks)
 
@@ -5477,5 +5513,6 @@  do
 done
 ], 
 [subdirs='$subdirs'])
+
 AC_OUTPUT
 
Index: gcc/ipa-utils.c
===================================================================
--- gcc/ipa-utils.c.orig
+++ gcc/ipa-utils.c
@@ -37,6 +37,7 @@  along with GCC; see the file COPYING3.
 #include "langhooks.h"
 #include "lto-streamer.h"
 #include "ipa-inline.h"
+#include "out-targets.h"
 
 /* Debugging function for postorder and inorder code. NOTE is a string
    that is printed before the nodes are printed.  ORDER is an array of
@@ -287,7 +288,6 @@  ipa_reverse_postorder (struct cgraph_nod
   struct cgraph_edge *edge;
   int pass;
   struct ipa_ref *ref;
-
   struct postorder_stack *stack =
     XCNEWVEC (struct postorder_stack, cgraph_n_nodes);
 
@@ -300,6 +300,7 @@  ipa_reverse_postorder (struct cgraph_nod
   for (pass = 0; pass < 2; pass++)
     FOR_EACH_FUNCTION (node)
       if (!node->aux
+	  && decl_matches_lto_target (node->decl)
 	  && (pass
 	      || (!node->address_taken
 		  && !node->global.inlined_to
Index: gcc/lto/lto-object.c
===================================================================
--- gcc/lto/lto-object.c.orig
+++ gcc/lto/lto-object.c
@@ -27,13 +27,9 @@  along with GCC; see the file COPYING3.
 #include "lto.h"
 #include "tm.h"
 #include "lto-streamer.h"
+#include "lto-section-names.h"
 #include "simple-object.h"
 
-/* Segment name for LTO sections.  This is only used for Mach-O.
-   FIXME: This needs to be kept in sync with darwin.c.  */
-
-#define LTO_SEGMENT_NAME "__GNU_LTO"
-
 /* An LTO file wrapped around an simple_object.  */
 
 struct lto_simple_object
@@ -215,6 +211,27 @@  struct lto_obj_add_section_data
   struct lto_section_list *list;
 };
 
+static bool
+section_name_matches_lto (const char *name)
+{
+  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
+	       strlen (LTO_SECTION_NAME_PREFIX)) == 0)
+    return true;
+#ifdef ACCEL_COMPILER
+  if (strncmp (name, LTO_TARGET_SECTION_NAME_PREFIX,
+	       strlen (LTO_TARGET_SECTION_NAME_PREFIX)) != 0)
+    return false;
+  name += strlen (LTO_TARGET_SECTION_NAME_PREFIX);
+  if (strncmp (name, ACCEL_TARGET, strlen (ACCEL_TARGET)) != 0)
+    return false;
+  name += strlen (ACCEL_TARGET);
+  if (*name == '_')
+    return true;
+#else
+  return false;
+#endif
+}
+
 /* This is called for each section in the file.  */
 
 static int
@@ -229,8 +246,7 @@  lto_obj_add_section (void *data, const c
   void **slot;
   struct lto_section_list *list = loasd->list;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
-	       strlen (LTO_SECTION_NAME_PREFIX)) != 0)
+  if (!section_name_matches_lto (name))
     return 1;
 
   new_name = xstrdup (name);
Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c.orig
+++ gcc/lto/lto.c
@@ -42,12 +42,14 @@  along with GCC; see the file COPYING3.
 #include "lto.h"
 #include "lto-tree.h"
 #include "lto-streamer.h"
+#include "lto-section-names.h"
 #include "tree-streamer.h"
 #include "splay-tree.h"
 #include "lto-partition.h"
 #include "data-streamer.h"
 #include "context.h"
 #include "pass_manager.h"
+#include "out-targets.h"
 
 /* Vector to keep track of external variables we've seen so far.  */
 vec<tree, va_gc> *lto_global_var_decls;
@@ -3201,6 +3203,7 @@  lto_process_name (void)
 static void
 lto_init (void)
 {
+  lto_set_target (built_in_target);
   lto_process_name ();
   lto_streamer_hooks_init ();
   lto_reader_init ();
Index: gcc/lto-cgraph.c
===================================================================
--- gcc/lto-cgraph.c.orig
+++ gcc/lto-cgraph.c
@@ -51,6 +51,7 @@  along with GCC; see the file COPYING3.
 #include "context.h"
 #include "pass_manager.h"
 #include "ipa-utils.h"
+#include "out-targets.h"
 
 static void output_cgraph_opt_summary (void);
 static void input_cgraph_opt_summary (vec<symtab_node *>  nodes);
@@ -836,7 +837,8 @@  compute_ltrans_boundary (lto_symtab_enco
       for (edge = node->callees; edge; edge = edge->next_callee)
 	{
 	  struct cgraph_node *callee = edge->callee;
-	  if (!lto_symtab_encoder_in_partition_p (encoder, callee))
+	  if (decl_matches_lto_target (callee->decl)
+	      && !lto_symtab_encoder_in_partition_p (encoder, callee))
 	    {
 	      /* We should have moved all the inlines.  */
 	      gcc_assert (!callee->global.inlined_to);
Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c.orig
+++ gcc/lto-streamer-out.c
@@ -50,7 +50,40 @@  along with GCC; see the file COPYING3.
 #include "tree-streamer.h"
 #include "streamer-hooks.h"
 #include "cfgloop.h"
+#include "out-targets.h"
 
+/* Keep track of the current target triplet for which we're emitting LTO
+   data.  */
+static target_machine *lto_out_target;
+
+void
+lto_set_target (target_machine *t)
+{
+  lto_out_target = t;
+}
+
+target_machine *
+lto_get_target ()
+{
+  return lto_out_target;
+}
+
+bool
+decl_matches_lto_target (const_tree decl)
+{
+  return (lto_out_target == NULL
+	  || DECL_TARGET (decl) == lto_out_target->get_decl_target ());
+}
+
+tree
+target_machine::get_decl_target ()
+{
+  if (id != NULL_TREE)
+    return id;
+  if (strcmp (triplet, "") == 0)
+    return NULL_TREE;
+  return get_identifier (triplet);
+}
 
 /* Clear the line info stored in DATA_IN.  */
 
Index: gcc/lto-streamer.c
===================================================================
--- gcc/lto-streamer.c.orig
+++ gcc/lto-streamer.c
@@ -33,7 +33,9 @@  along with GCC; see the file COPYING3.
 #include "vec.h"
 #include "tree-streamer.h"
 #include "lto-streamer.h"
+#include "lto-section-names.h"
 #include "streamer-hooks.h"
+#include "out-targets.h"
 
 /* Statistics gathered during LTO, WPA and LTRANS.  */
 struct lto_stats_d lto_stats;
@@ -171,8 +173,13 @@  lto_get_section_name (int section_type,
   else if (f != NULL) 
     sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id);
   else
-    sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false)); 
-  return concat (LTO_SECTION_NAME_PREFIX, sep, add, post, NULL);
+    sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false));
+  target_machine *m = lto_get_target ();
+  if (m == built_in_target)
+    return concat (LTO_SECTION_NAME_PREFIX, sep, add, post, NULL);
+
+  return concat (LTO_TARGET_SECTION_NAME_PREFIX, m->triplet, "_",
+		 sep, add, post, NULL);
 }
 
 
Index: gcc/lto-streamer.h
===================================================================
--- gcc/lto-streamer.h.orig
+++ gcc/lto-streamer.h
@@ -134,12 +134,6 @@  along with GCC; see the file COPYING3.
      String are represented in the table as pairs, a length in ULEB128
      form followed by the data for the string.  */
 
-/* The string that is the prefix on the section names we make for lto.
-   For decls the DECL_ASSEMBLER_NAME is appended to make the section
-   name for the functions and static_initializers.  For other types of
-   sections a '.' and the section type are appended.  */
-#define LTO_SECTION_NAME_PREFIX         ".gnu.lto_"
-
 #define LTO_major_version 2
 #define LTO_minor_version 2
 
Index: gcc/lto-wrapper.c
===================================================================
--- gcc/lto-wrapper.c.orig
+++ gcc/lto-wrapper.c
@@ -46,11 +46,7 @@  along with GCC; see the file COPYING3.
 #include "opts.h"
 #include "options.h"
 #include "simple-object.h"
-
-/* From lto-streamer.h which we cannot include with -fkeep-inline-functions.
-   ???  Split out a lto-streamer-core.h.  */
-
-#define LTO_SECTION_NAME_PREFIX         ".gnu.lto_"
+#include "lto-section-names.h"
 
 /* End of lto-streamer.h copy.  */
 
Index: gcc/omp-low.c
===================================================================
--- gcc/omp-low.c.orig
+++ gcc/omp-low.c
@@ -64,7 +64,7 @@  along with GCC; see the file COPYING3.
 #include "pretty-print.h"
 #include "ipa-prop.h"
 #include "tree-nested.h"
-
+#include "out-targets.h"
 
 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
    phases.  The first phase scans the function looking for OMP statements
@@ -2003,6 +2003,9 @@  scan_oacc_parallel (gimple stmt, omp_con
   DECL_NAMELESS (name) = 1;
   TYPE_NAME (ctx->record_type) = name;
   create_omp_child_function (ctx, false);
+#ifdef ACCEL_TARGET
+  DECL_TARGET (ctx->cb.dst_fn) = openacc_target->get_decl_target ();
+#endif
   gimple_oacc_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
 
   scan_sharing_clauses (gimple_oacc_parallel_clauses (stmt), ctx);
Index: gcc/passes.c
===================================================================
--- gcc/passes.c.orig
+++ gcc/passes.c
@@ -82,6 +82,7 @@  along with GCC; see the file COPYING3.
 #include "pass_manager.h"
 #include "tree-ssa-live.h"  /* For remove_unused_locals.  */
 #include "tree-cfgcleanup.h"
+#include "out-targets.h"
 
 using namespace gcc;
 
@@ -2326,7 +2327,7 @@  ipa_write_summaries_2 (struct opt_pass *
    summaries.  SET is the set of nodes to be written.  */
 
 static void
-ipa_write_summaries_1 (lto_symtab_encoder_t encoder)
+ipa_write_summaries_1 (lto_symtab_encoder_t encoder, bool lto_only)
 {
   pass_manager *passes = g->get_passes ();
   struct lto_out_decl_state *state = lto_new_out_decl_state ();
@@ -2335,7 +2336,8 @@  ipa_write_summaries_1 (lto_symtab_encode
   lto_push_out_decl_state (state);
 
   gcc_assert (!flag_wpa);
-  ipa_write_summaries_2 (passes->all_regular_ipa_passes, state);
+  if (!lto_only)
+    ipa_write_summaries_2 (passes->all_regular_ipa_passes, state);
 
   write_lto ();
 
@@ -2349,54 +2351,67 @@  ipa_write_summaries_1 (lto_symtab_encode
 void
 ipa_write_summaries (void)
 {
-  lto_symtab_encoder_t encoder;
-  int i, order_pos;
-  struct varpool_node *vnode;
-  struct cgraph_node *node;
-  struct cgraph_node **order;
-
-  if (!flag_generate_lto || seen_error ())
+  if (seen_error ())
     return;
 
-  encoder = lto_symtab_encoder_new (false);
-
-  /* Create the callgraph set in the same order used in
-     cgraph_expand_all_functions.  This mostly facilitates debugging,
-     since it causes the gimple file to be processed in the same order
-     as the source code.  */
-  order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
-  order_pos = ipa_reverse_postorder (order);
-  gcc_assert (order_pos == cgraph_n_nodes);
+  if (!flag_generate_lto && !flag_openacc)
+    return;
+  
+  unsigned i;
+  target_machine *m;
+  FOR_EACH_VEC_ELT (target_machines, i, m)
+    {
+      if (m->built_in && !flag_generate_lto)
+	continue;
+
+      lto_set_target (m);
+
+      lto_symtab_encoder_t encoder = lto_symtab_encoder_new (false);
+
+      /* Create the callgraph set in the same order used in
+	 cgraph_expand_all_functions.  This mostly facilitates debugging,
+	 since it causes the gimple file to be processed in the same order
+	 as the source code.  */
+      struct cgraph_node **order
+	= XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+      int order_pos = ipa_reverse_postorder (order);
+#if 0
+      gcc_assert (order_pos == cgraph_n_nodes);
+#endif
+      for (int i = order_pos - 1; i >= 0; i--)
+	{
+	  struct cgraph_node *node = order[i];
 
-  for (i = order_pos - 1; i >= 0; i--)
-    {
-      struct cgraph_node *node = order[i];
+	  if (cgraph_function_with_gimple_body_p (node))
+	    {
+	      /* When streaming out references to statements as part of some IPA
+		 pass summary, the statements need to have uids assigned and the
+		 following does that for all the IPA passes here. Naturally, this
+		 ordering then matches the one IPA-passes get in their stmt_fixup
+		 hooks.  */
 
-      if (cgraph_function_with_gimple_body_p (node))
-	{
-	  /* When streaming out references to statements as part of some IPA
-	     pass summary, the statements need to have uids assigned and the
-	     following does that for all the IPA passes here. Naturally, this
-	     ordering then matches the one IPA-passes get in their stmt_fixup
-	     hooks.  */
-
-	  push_cfun (DECL_STRUCT_FUNCTION (node->decl));
-	  renumber_gimple_stmt_uids ();
-	  pop_cfun ();
+	      push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+	      renumber_gimple_stmt_uids ();
+	      pop_cfun ();
+	    }
+	  if (node->definition)
+	    lto_set_symtab_encoder_in_partition (encoder, node);
 	}
-      if (node->definition)
-        lto_set_symtab_encoder_in_partition (encoder, node);
-    }
+      struct cgraph_node *node;
+      FOR_EACH_DEFINED_FUNCTION (node)
+	if (node->alias)
+	  lto_set_symtab_encoder_in_partition (encoder, node);
 
-  FOR_EACH_DEFINED_FUNCTION (node)
-    if (node->alias)
-      lto_set_symtab_encoder_in_partition (encoder, node);
-  FOR_EACH_DEFINED_VARIABLE (vnode)
-    lto_set_symtab_encoder_in_partition (encoder, vnode);
+      struct varpool_node *vnode;
+      FOR_EACH_DEFINED_VARIABLE (vnode)
+	lto_set_symtab_encoder_in_partition (encoder, vnode);
 
-  ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
+      ipa_write_summaries_1 (compute_ltrans_boundary (encoder),
+			     m != built_in_target);
 
-  free (order);
+      free (order);
+    }
+  lto_set_target (NULL);
 }
 
 /* Same as execute_pass_list but assume that subpasses of IPA passes
Index: gcc/streamer-hooks.c
===================================================================
--- gcc/streamer-hooks.c.orig
+++ gcc/streamer-hooks.c
@@ -27,7 +27,7 @@  along with GCC; see the file COPYING3.
 #include "streamer-hooks.h"
 
 /* Streamer hooks.  */
-struct streamer_hooks streamer_hooks;
+struct streamer_hooks_s streamer_hooks;
 
 /* Initialize the current set of streamer hooks.  */
 
Index: gcc/streamer-hooks.h
===================================================================
--- gcc/streamer-hooks.h.orig
+++ gcc/streamer-hooks.h
@@ -34,7 +34,7 @@  struct data_in;
 
    Hooks marked [REQ] are required to be set.  Those marked [OPT] may
    be NULL, if the streamer does not need to implement them.  */
-struct streamer_hooks {
+struct streamer_hooks_s {
   /* [REQ] Called by every tree streaming routine that needs to write
      a tree node.  The arguments are: output_block where to write the
      node, the tree node to write and a boolean flag that should be true
@@ -74,7 +74,7 @@  struct streamer_hooks {
     streamer_hooks.output_location (OB, BP, LOC)
 
 /* Streamer hooks.  */
-extern struct streamer_hooks streamer_hooks;
+extern struct streamer_hooks_s streamer_hooks;
 
 /* In streamer-hooks.c.  */
 void streamer_hooks_init (void);
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c.orig
+++ gcc/toplev.c
@@ -78,6 +78,7 @@  along with GCC; see the file COPYING3.
 #include "diagnostic-color.h"
 #include "context.h"
 #include "pass_manager.h"
+#include "out-targets.h"
 
 #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
 #include "dbxout.h"
@@ -1964,6 +1965,8 @@  toplev_main (int argc, char **argv)
   if (help_flag)
     print_plugins_help (stderr, "");
 
+  init_out_targets ();
+
   /* Exit early if we can (e.g. -help).  */
   if (!exit_after_options)
     do_compile ();
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h.orig
+++ gcc/tree-core.h
@@ -1368,6 +1368,8 @@  struct GTY(()) tree_decl_common {
   tree attributes;
   tree abstract_origin;
 
+  tree target;
+
   /* Points to a structure whose details depend on the language in use.  */
   struct lang_decl *lang_specific;
 };
Index: gcc/tree.h
===================================================================
--- gcc/tree.h.orig
+++ gcc/tree.h
@@ -2264,6 +2264,9 @@  extern void decl_value_expr_insert (tree
 #define DECL_NONADDRESSABLE_P(NODE) \
   (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_2)
 
+#define DECL_TARGET(NODE) \
+  (DECL_COMMON_CHECK (NODE)->decl_common.target)
+
 /* A numeric unique identifier for a LABEL_DECL.  The UID allocation is
    dense, unique within any one function, and may be used to index arrays.
    If the value is -1, then no UID has been assigned.  */
Index: gcc/lto-section-names.h
===================================================================
--- /dev/null
+++ gcc/lto-section-names.h
@@ -0,0 +1,29 @@ 
+/* Definitions for LTO section names.
+   Copyright (C) 2013 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.
+
+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/>.  */
+
+/* The string that is the prefix on the section names we make for lto.
+   For decls the DECL_ASSEMBLER_NAME is appended to make the section
+   name for the functions and static_initializers.  For other types of
+   sections a '.' and the section type are appended.  */
+#define LTO_SECTION_NAME_PREFIX ".gnu.lto_"
+#define LTO_TARGET_SECTION_NAME_PREFIX ".gnu.tlto_"
+
+/* Segment name for LTO sections.  This is only used for Mach-O.  */
+
+#define LTO_SEGMENT_NAME "__GNU_LTO"
Index: gcc/out-targets.h
===================================================================
--- /dev/null
+++ gcc/out-targets.h
@@ -0,0 +1,47 @@ 
+/* Data structure definitions for compiler targets.
+   Copyright (C) 2001-2013 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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 this program; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.
+
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!  */
+
+/* Describe a target that can be targetted by this compiler - either
+   directly, or by streaming out IR to be used by a different lto1.  */
+class GTY(()) target_machine
+{
+  tree id;
+ public:
+  const char *triplet;
+  bool built_in;
+  bool used;
+
+  target_machine (const char *t, bool bi)
+    : id (0), triplet (t), built_in (bi), used (false)
+  {
+  }
+  tree get_decl_target ();
+};
+
+extern vec<target_machine *> target_machines;
+extern target_machine *built_in_target;
+extern target_machine *openacc_target;
+
+extern void lto_set_target (target_machine *);
+extern target_machine *lto_get_target ();
+extern bool decl_matches_lto_target (const_tree decl);
+
+extern void init_out_targets ();
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in.orig
+++ gcc/Makefile.in
@@ -66,6 +66,11 @@  program_transform_name := @program_trans
 # Directories used during build
 # -----------------------------
 
+# Normally identical to target_noncanonical, except for compilers built
+# as accelerator targets.
+install_dirname=@install_dirname@
+tool_prefix = @tool_prefix@
+
 # Directory where sources are, from where we are.
 srcdir = @srcdir@
 gcc_docdir = @srcdir@/doc
@@ -351,6 +356,8 @@  enable_plugin = @enable_plugin@
 
 enable_host_shared = @enable_host_shared@
 
+enable_as_accelerator = @enable_as_accelerator@
+
 CPPLIB = ../libcpp/libcpp.a
 CPPINC = -I$(srcdir)/../libcpp/include
 
@@ -586,9 +593,9 @@  libexecdir = @libexecdir@
 # --------
 
 # Directory in which the compiler finds libraries etc.
-libsubdir = $(libdir)/gcc/$(target_noncanonical)/$(version)
+libsubdir = $(libdir)/gcc/$(install_dirname)/$(version)
 # Directory in which the compiler finds executables
-libexecsubdir = $(libexecdir)/gcc/$(target_noncanonical)/$(version)
+libexecsubdir = $(libexecdir)/gcc/$(install_dirname)/$(version)
 # Directory in which all plugin resources are installed
 plugin_resourcesdir = $(libsubdir)/plugin
  # Directory in which plugin headers are installed
@@ -632,7 +639,7 @@  dollar = @dollar@
 # Used in install-cross.
 gcc_tooldir = @gcc_tooldir@
 # Since gcc_tooldir does not exist at build-time, use -B$(build_tooldir)/bin/
-build_tooldir = $(exec_prefix)/$(target_noncanonical)
+build_tooldir = $(exec_prefix)/$(install_dirname)
 # Directory in which the compiler finds target-independent g++ includes.
 gcc_gxx_include_dir = @gcc_gxx_include_dir@
 gcc_gxx_include_dir_add_sysroot = @gcc_gxx_include_dir_add_sysroot@
@@ -765,7 +772,7 @@  BUILD_CPPFLAGS=$(ALL_CPPFLAGS)
 
 # Actual name to use when installing a native compiler.
 GCC_INSTALL_NAME := $(shell echo gcc|sed '$(program_transform_name)')
-GCC_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gcc|sed '$(program_transform_name)')
+GCC_TARGET_INSTALL_NAME := $(tool_prefix)-$(shell echo gcc|sed '$(program_transform_name)')
 CPP_INSTALL_NAME := $(shell echo cpp|sed '$(program_transform_name)')
 GCOV_INSTALL_NAME := $(shell echo gcov|sed '$(program_transform_name)')
 
@@ -1320,6 +1327,7 @@  OBJS = \
 	optabs.o \
 	options-save.o \
 	opts-global.o \
+	out-targets.o \
 	passes.o \
 	plugin.o \
 	pointer-set.o \
@@ -2528,7 +2536,7 @@  PREPROCESSOR_DEFINES = \
   -DFIXED_INCLUDE_DIR=\"$(libsubdir)/include-fixed\" \
   -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
   -DGPLUSPLUS_INCLUDE_DIR_ADD_SYSROOT=$(gcc_gxx_include_dir_add_sysroot) \
-  -DGPLUSPLUS_TOOL_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/$(target_noncanonical)\" \
+  -DGPLUSPLUS_TOOL_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/$(install_dirname)\" \
   -DGPLUSPLUS_BACKWARD_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/backward\" \
   -DLOCAL_INCLUDE_DIR=\"$(local_includedir)\" \
   -DCROSS_INCLUDE_DIR=\"$(CROSS_SYSTEM_HEADER_DIR)\" \
@@ -3194,16 +3202,18 @@  install-common: native lang.install-comm
 # Install the driver program as $(target_noncanonical)-gcc,
 # $(target_noncanonical)-gcc-$(version), and also as gcc if native.
 install-driver: installdirs xgcc$(exeext)
-	-rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext)
-	-$(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext)
-	-rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-$(version)$(exeext)
+	-@if test "@enable_as_accelerator@" != "yes" ; then \
+	rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext); \
+	$(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext); \
+	fi
+	-rm -f $(DESTDIR)$(bindir)/$(tool_prefix)-gcc-$(version)$(exeext)
 	-( cd $(DESTDIR)$(bindir) && \
-	   $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-$(version)$(exeext) )
+	   $(LN) $(GCC_INSTALL_NAME)$(exeext) $(tool_prefix)-gcc-$(version)$(exeext) )
 	-if [ ! -f gcc-cross$(exeext) ] ; then \
-	  rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-tmp$(exeext); \
+	  rm -f $(DESTDIR)$(bindir)/$(tool_prefix)-gcc-tmp$(exeext); \
 	  ( cd $(DESTDIR)$(bindir) && \
-	    $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-tmp$(exeext) && \
-	    mv -f $(target_noncanonical)-gcc-tmp$(exeext) $(GCC_TARGET_INSTALL_NAME)$(exeext) ); \
+	    $(LN) $(GCC_INSTALL_NAME)$(exeext) $(tool_prefix)-gcc-tmp$(exeext) && \
+	    mv -f $(tool_prefix)-gcc-tmp$(exeext) $(GCC_TARGET_INSTALL_NAME)$(exeext) ); \
 	fi
 
 # Install the info files.
Index: gcc/out-targets.c
===================================================================
--- /dev/null
+++ gcc/out-targets.c
@@ -0,0 +1,48 @@ 
+/* Definitions for output targets.
+   Copyright (C) 2013 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.
+
+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 "vec.h"
+#include "out-targets.h"
+
+/* A vector of target machines for which we can generate code directly,
+   or through streaming out IR to a different lto1.  */
+GTY(()) vec<target_machine *> target_machines;
+/* The target built into this compiler.  */
+target_machine *built_in_target;
+/* The target for OpenACC off-loading, if any.  */
+target_machine *openacc_target;
+
+void
+init_out_targets ()
+{
+#ifdef ACCEL_COMPILER
+  built_in_target = new target_machine (ACCEL_TARGET, true);
+  target_machines.safe_push (built_in_target);
+#else
+  built_in_target = new target_machine ("", true);
+  target_machines.safe_push (built_in_target);
+#ifdef ACCEL_TARGET
+  openacc_target = new target_machine (ACCEL_TARGET, false);
+  target_machines.safe_push (openacc_target);
+#endif
+#endif
+}