From 3bd36029de1b586b49b3b021385b275ba5427611 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 12 Jul 2010 18:53:01 +0000 Subject: tm.texi.in (SWITCHABLE_TARGET): Document. gcc/ * doc/tm.texi.in (SWITCHABLE_TARGET): Document. * doc/tm.texi: Regenerate. * Makefile.in (OBJS-common): Add target-globals.o. (gtype-desc.o): Depend on $(IPA_PROP_H), $(LTO_STREAMER_H) and target-globals.h. (target-globals.o): New rule. (GTFILES): Include $(srcdir)/target-globals.h. * defaults.h (SWITCHABLE_TARGET): Define. * gengtype.c (open_base_files): Add target-globals.h to the list of includes. * target-globals.h: New file. * target-globals.c: Likewise. * Makefile.in (target-globals.o): Depend on $(FLAGS_H). * flags.h (target_flag_state): New structure. (default_target_flag_state): Declare. (this_target_flag_state): Declare as a variable or define as a macro. (align_loops_log): Redefine as a macro. (align_loops_max_skip, align_jumps_log): Likewise. (align_jumps_max_skip, align_labels_log): Likewise. (align_labels_max_skip, align_functions_log): Likewise. * toplev.c (default_target_flag_state): New variable. (this_target_flag_state): New conditional variable. (align_loops_log): Delete. (align_loops_max_skip, align_jumps_log): Likewise. (align_jumps_max_skip, align_labels_log): Likewise. (align_labels_max_skip, align_functions_log): Likewise. * target-globals.h (this_target_flag_state): Declare. (target_globals): Add a flag_state field. (restore_target_globals): Copy the flag_state field to this_target_flag_state. * target-globals.c: Include flags.h. (default_target_globals): Initialize the flag_state field. (save_target_globals): Likewise. From-SVN: r162086 --- gcc/ChangeLog | 37 +++++++++++++++++++++++++++++++++++++ gcc/Makefile.in | 8 +++++++- gcc/defaults.h | 4 ++++ gcc/doc/tm.texi | 19 +++++++++++++++++++ gcc/doc/tm.texi.in | 19 +++++++++++++++++++ gcc/flags.h | 50 +++++++++++++++++++++++++++++++++++++------------- gcc/gengtype.c | 2 +- gcc/target-globals.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/target-globals.h | 41 +++++++++++++++++++++++++++++++++++++++++ gcc/toplev.c | 18 ++++++------------ 10 files changed, 219 insertions(+), 27 deletions(-) create mode 100644 gcc/target-globals.c create mode 100644 gcc/target-globals.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2cd8630..aa2ef84 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,40 @@ +2010-07-12 Richard Sandiford + + * doc/tm.texi.in (SWITCHABLE_TARGET): Document. + * doc/tm.texi: Regenerate. + * Makefile.in (OBJS-common): Add target-globals.o. + (gtype-desc.o): Depend on $(IPA_PROP_H), $(LTO_STREAMER_H) + and target-globals.h. + (target-globals.o): New rule. + (GTFILES): Include $(srcdir)/target-globals.h. + * defaults.h (SWITCHABLE_TARGET): Define. + * gengtype.c (open_base_files): Add target-globals.h to the + list of includes. + * target-globals.h: New file. + * target-globals.c: Likewise. + + * Makefile.in (target-globals.o): Depend on $(FLAGS_H). + * flags.h (target_flag_state): New structure. + (default_target_flag_state): Declare. + (this_target_flag_state): Declare as a variable or define as a macro. + (align_loops_log): Redefine as a macro. + (align_loops_max_skip, align_jumps_log): Likewise. + (align_jumps_max_skip, align_labels_log): Likewise. + (align_labels_max_skip, align_functions_log): Likewise. + * toplev.c (default_target_flag_state): New variable. + (this_target_flag_state): New conditional variable. + (align_loops_log): Delete. + (align_loops_max_skip, align_jumps_log): Likewise. + (align_jumps_max_skip, align_labels_log): Likewise. + (align_labels_max_skip, align_functions_log): Likewise. + * target-globals.h (this_target_flag_state): Declare. + (target_globals): Add a flag_state field. + (restore_target_globals): Copy the flag_state field to + this_target_flag_state. + * target-globals.c: Include flags.h. + (default_target_globals): Initialize the flag_state field. + (save_target_globals): Likewise. + 2010-07-12 Jie Zhang * postreload.c (reg_symbol_ref[]): New. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index a807e8e..6fd3b00 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1337,6 +1337,7 @@ OBJS-common = \ stor-layout.o \ store-motion.o \ stringpool.o \ + target-globals.o \ targhooks.o \ timevar.o \ toplev.o \ @@ -2249,7 +2250,8 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_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) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h \ @@ -3473,6 +3475,9 @@ lower-subreg.o : lower-subreg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(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 \ + $(FLAGS_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 \ @@ -3750,6 +3755,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(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, diff --git a/gcc/defaults.h b/gcc/defaults.h index e7e32c4..5d56c75 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -1372,6 +1372,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #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 */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index d3d9c1e..78f2f2f 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -842,6 +842,25 @@ pointer. If this macro is defined, GCC will turn on the @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 diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 51a8e5e..2f35a42 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -842,6 +842,25 @@ pointer. If this macro is defined, GCC will turn on the @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 diff --git a/gcc/flags.h b/gcc/flags.h index 5e87c09..32f9fbf 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -239,6 +239,43 @@ extern enum excess_precision flag_excess_precision; /* Other basic status info about current function. */ +/* Target-dependent global state. */ +struct target_flag_state { + /* Values of the -falign-* flags: how much to align labels in code. + 0 means `use default', 1 means `don't align'. + For each variable, there is an _log variant which is the power + of two not less than the variable, for .align output. */ + int x_align_loops_log; + int x_align_loops_max_skip; + int x_align_jumps_log; + int x_align_jumps_max_skip; + int x_align_labels_log; + int x_align_labels_max_skip; + int x_align_functions_log; +}; + +extern struct target_flag_state default_target_flag_state; +#if SWITCHABLE_TARGET +extern struct target_flag_state *this_target_flag_state; +#else +#define this_target_flag_state (&default_target_flag_state) +#endif + +#define align_loops_log \ + (this_target_flag_state->x_align_loops_log) +#define align_loops_max_skip \ + (this_target_flag_state->x_align_loops_max_skip) +#define align_jumps_log \ + (this_target_flag_state->x_align_jumps_log) +#define align_jumps_max_skip \ + (this_target_flag_state->x_align_jumps_max_skip) +#define align_labels_log \ + (this_target_flag_state->x_align_labels_log) +#define align_labels_max_skip \ + (this_target_flag_state->x_align_labels_max_skip) +#define align_functions_log \ + (this_target_flag_state->x_align_functions_log) + /* Nonzero if subexpressions must be evaluated from left-to-right. */ extern int flag_evaluation_order; @@ -252,19 +289,6 @@ extern bool sel_sched_switch_set; /* Whether to run the warn_unused_result attribute pass. */ extern bool flag_warn_unused_result; -/* Values of the -falign-* flags: how much to align labels in code. - 0 means `use default', 1 means `don't align'. - For each variable, there is an _log variant which is the power - of two not less than the variable, for .align output. */ - -extern int align_loops_log; -extern int align_loops_max_skip; -extern int align_jumps_log; -extern int align_jumps_max_skip; -extern int align_labels_log; -extern int align_labels_max_skip; -extern int align_functions_log; - /* Nonzero if we dump in VCG format, not plain text. */ extern int dump_for_graph; diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 4b6e60e..9127251 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -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; diff --git a/gcc/target-globals.c b/gcc/target-globals.c new file mode 100644 index 0000000..ecbc76b --- /dev/null +++ b/gcc/target-globals.c @@ -0,0 +1,48 @@ +/* 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 +. */ + +#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" +#include "flags.h" + +#if SWITCHABLE_TARGET +struct target_globals default_target_globals = { + &default_target_flag_state +}; + +struct target_globals * +save_target_globals (void) +{ + struct target_globals *g; + + g = ggc_alloc_target_globals (); + g->flag_state = XCNEW (struct target_flag_state); + restore_target_globals (g); + target_reinit (); + return g; +} + +#endif diff --git a/gcc/target-globals.h b/gcc/target-globals.h new file mode 100644 index 0000000..496a507 --- /dev/null +++ b/gcc/target-globals.h @@ -0,0 +1,41 @@ +/* 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 +. */ + +#ifndef TARGET_GLOBALS_H +#define TARGET_GLOBALS_H 1 + +#if SWITCHABLE_TARGET +extern struct target_flag_state *this_target_flag_state; + +struct GTY(()) target_globals { + struct target_flag_state *GTY((skip)) flag_state; +}; + +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) +{ + this_target_flag_state = g->flag_state; +} +#endif + +#endif diff --git a/gcc/toplev.c b/gcc/toplev.c index 276ae7e..1472579 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -317,18 +317,12 @@ enum stack_check_type flag_stack_check = NO_STACK_CHECK; bool user_defined_section_attribute = false; -/* Values of the -falign-* flags: how much to align labels in code. - 0 means `use default', 1 means `don't align'. - For each variable, there is an _log variant which is the power - of two not less than the variable, for .align output. */ - -int align_loops_log; -int align_loops_max_skip; -int align_jumps_log; -int align_jumps_max_skip; -int align_labels_log; -int align_labels_max_skip; -int align_functions_log; +struct target_flag_state default_target_flag_state; +#if SWITCHABLE_TARGET +struct target_flag_state *this_target_flag_state = &default_target_flag_state; +#else +#define this_target_flag_state (&default_target_flag_state) +#endif typedef struct { -- cgit v1.1