Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	2010-07-04 13:56:55.000000000 +0100
+++ gcc/doc/tm.texi.in	2010-07-04 13:59:38.000000000 +0100
@@ -842,6 +842,25 @@ pointer.  If this macro is defined, GCC
 @option{-fomit-frame-pointer} option whenever @option{-O} is specified.
 @end defmac
 
+@defmac SWITCHABLE_TARGET
+Some targets need to switch between substantially different subtargets
+during compilation.  For example, the MIPS target has one subtarget for
+the traditional MIPS architecture and another for MIPS16.  Source code
+can switch between these two subarchitectures using the @code{mips16}
+and @code{nomips16} attributes.
+
+Such subtargets can differ in things like the set of available
+registers, the set of available instructions, the costs of various
+operations, and so on.  GCC caches a lot of this type of information
+in global variables, and recomputing them for each subtarget takes a
+significant amount of time.  The compiler therefore provides a facility
+for maintaining several versions of the global variables and quickly
+switching between them; see @file{target-globals.h} for details.
+
+Define this macro to 1 if your target needs this facility.  The default
+is 0.
+@end defmac
+
 @node Per-Function Data
 @section Defining data structures for per-function information.
 @cindex per-function data
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	2010-07-04 13:59:31.000000000 +0100
+++ gcc/Makefile.in	2010-07-04 14:13:10.000000000 +0100
@@ -1338,6 +1338,7 @@ OBJS-common = \
 	stor-layout.o \
 	store-motion.o \
 	stringpool.o \
+	target-globals.o \
 	targhooks.o \
 	timevar.o \
 	toplev.o \
@@ -2251,7 +2252,8 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $
 	hard-reg-set.h $(BASIC_BLOCK_H) cselib.h $(INSN_ADDR_H) $(OPTABS_H) \
 	$(LIBFUNCS_H) debug.h $(GGC_H) $(CGRAPH_H) $(TREE_FLOW_H) reload.h \
 	$(CPP_ID_DATA_H) tree-chrec.h $(CFGLAYOUT_H) $(EXCEPT_H) output.h \
-	$(CFGLOOP_H) $(TARGET_H)
+	$(CFGLOOP_H) $(TARGET_H) $(IPA_PROP_H) $(LTO_STREAMER_H) \
+	target-globals.h
 
 ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h		\
 	$(GGC_H) $(HASHTAB_H) $(TOPLEV_H) $(PARAMS_H) hosthooks.h	\
@@ -3475,6 +3477,8 @@ lower-subreg.o : lower-subreg.c $(CONFIG
    $(MACHMODE_H) $(TM_H) $(RTL_H) $(TM_P_H) $(TIMEVAR_H) $(FLAGS_H) \
    insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) $(OBSTACK_H) $(BITMAP_H) \
    $(EXPR_H) $(EXCEPT_H) $(REGS_H) $(TREE_PASS_H) $(DF_H)
+target-globals.o : target-globals.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+   $(TM_H) insn-config.h $(MACHMODE_H) $(GGC_H) $(TOPLEV_H) target-globals.h
 
 $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
    $(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
@@ -3752,6 +3756,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/inp
   $(srcdir)/tree-ssa-alias.h \
   $(srcdir)/ipa-prop.h \
   $(srcdir)/lto-streamer.h \
+  $(srcdir)/target-globals.h \
   @all_gtfiles@
 
 # Compute the list of GT header files from the corresponding C sources,
Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h	2010-07-04 13:56:55.000000000 +0100
+++ gcc/defaults.h	2010-07-04 14:11:45.000000000 +0100
@@ -1364,6 +1364,10 @@ #define STACK_CHECK_FIXED_FRAME_SIZE (4
 #define STACK_CHECK_MAX_VAR_SIZE (STACK_CHECK_MAX_FRAME_SIZE / 100)
 #endif
 
+#ifndef SWITCHABLE_TARGET
+#define SWITCHABLE_TARGET 0
+#endif
+
 #endif /* GCC_INSN_FLAGS_H  */
 
 #endif  /* ! GCC_DEFAULTS_H */
Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c	2010-07-04 13:56:55.000000000 +0100
+++ gcc/gengtype.c	2010-07-04 13:59:38.000000000 +0100
@@ -1571,7 +1571,7 @@ open_base_files (void)
       "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
       "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
       "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
-      "target.h", "ipa-prop.h", "lto-streamer.h", NULL
+      "target.h", "ipa-prop.h", "lto-streamer.h", "target-globals.h", NULL
     };
     const char *const *ifp;
     outf_p gtype_desc_c;
Index: gcc/target-globals.h
===================================================================
--- /dev/null	2010-07-04 09:48:55.139146167 +0100
+++ gcc/target-globals.h	2010-07-04 14:12:37.000000000 +0100
@@ -0,0 +1,37 @@
+/* Target-dependent globals.
+   Copyright (C) 2010  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/>.  */
+
+#ifndef TARGET_GLOBALS_H
+#define TARGET_GLOBALS_H 1
+
+#if SWITCHABLE_TARGET
+struct GTY(()) target_globals {
+};
+
+extern struct target_globals default_target_globals;
+
+extern struct target_globals *save_target_globals (void);
+
+static inline void
+restore_target_globals (struct target_globals *g)
+{
+}
+#endif
+
+#endif
Index: gcc/target-globals.c
===================================================================
--- /dev/null	2010-07-04 09:48:55.139146167 +0100
+++ gcc/target-globals.c	2010-07-04 14:12:49.000000000 +0100
@@ -0,0 +1,45 @@
+/* Target-dependent globals.
+   Copyright (C) 2010  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 "tm.h"
+#include "insn-config.h"
+#include "machmode.h"
+#include "ggc.h"
+#include "toplev.h"
+#include "target-globals.h"
+
+#if SWITCHABLE_TARGET
+struct target_globals default_target_globals = {
+};
+
+struct target_globals *
+save_target_globals (void)
+{
+  struct target_globals *g;
+
+  g = ggc_alloc_target_globals ();
+  restore_target_globals (g);
+  target_reinit ();
+  return g;
+}
+
+#endif
