From patchwork Wed Jul 7 21:07:43 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [15/27] Use target structures for libfuncs Date: Wed, 07 Jul 2010 11:07:43 -0000 From: Richard Sandiford X-Patchwork-Id: 58180 Message-Id: <87aaq3t2zk.fsf@firetop.home> To: gcc-patches@gcc.gnu.org This patch completes the transition for init_optabs by handling the libfuncs stuff. Three related changes: - It fixes the comments above hash_libfunc and eq_libfunc - It uses libfunc_hash variable to detect whether the structure has already been initialised. A static "reinit" variable isn't enough when using multiple target structures. - It clears the libfunc_hash rather than creating a new one from scratch. Richard gcc/ * Makefile.in (LIBFUNCS_H): Add $(HASHTAB_H). (target-globals.o): Depend on $(LIBFUNCS_H). * libfuncs.h: Include hashtab.h. (libfunc_entry): Moved from optabs.c. (target_libfuncs): New structure. (default_target_libfuncs): Declare. (this_target_libfuncs): Declare as a variable or define as a macro. (libfunc_table): Redefine as a macro. * optabs.c (default_target_libfuncs): New variable. (this_target_libfuncs): New conditional variable. (libfunc_table): Delete. (libfunc_entry): Moved to optabs.h. (libfunc_hash): Redefine as a macro. (hash_libfunc, eq_libfunc): Fix comments. (init_optabs): Use libfunc_hash to detect cases where the function has already been called. Clear the hash table instead of recreating it. * target-globals.h (this_target_libfuncs): Declare. (target_globals): Add a libfuncs field. (restore_target_globals): Copy the libfuncs field to this_target_libfuncs. * target-globals.c: Include libfuncs.h. (default_target_globals): Initialize the libfuncs field. (save_target_globals): Likewise. Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in 2010-07-04 14:18:34.000000000 +0100 +++ gcc/Makefile.in 2010-07-04 14:18:47.000000000 +0100 @@ -969,7 +969,7 @@ GCC_PLUGIN_H = gcc-plugin.h highlev-plug $(HASHTAB_H) PLUGIN_H = plugin.h $(GCC_PLUGIN_H) PLUGIN_VERSION_H = plugin-version.h configargs.h -LIBFUNCS_H = libfuncs.h +LIBFUNCS_H = libfuncs.h $(HASHTAB_H) # # Now figure out from those variables how to compile and link. @@ -3478,7 +3478,8 @@ lower-subreg.o : lower-subreg.c $(CONFIG $(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) $(REGS_H) $(RTL_H) reload.h expmed.h $(EXPR_H) $(OPTABS_H) + $(FLAGS_H) $(REGS_H) $(RTL_H) reload.h expmed.h $(EXPR_H) $(OPTABS_H) \ + $(LIBFUNCS_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 \ Index: gcc/libfuncs.h =================================================================== --- gcc/libfuncs.h 2010-07-04 14:15:01.000000000 +0100 +++ gcc/libfuncs.h 2010-07-04 14:18:38.000000000 +0100 @@ -20,6 +20,8 @@ the Free Software Foundation; either ver #ifndef GCC_LIBFUNCS_H #define GCC_LIBFUNCS_H +#include "hashtab.h" + /* Enumeration of indexes into libfunc_table. */ enum libfunc_index { @@ -45,9 +47,34 @@ enum libfunc_index LTI_MAX }; -/* SYMBOL_REF rtx's for the library functions that are called - implicitly and not via optabs. */ -extern GTY(()) rtx libfunc_table[LTI_MAX]; +/* Information about an optab-related libfunc. We use the same hashtable + for normal optabs and conversion optabs. In the first case mode2 + is unused. */ +struct GTY(()) libfunc_entry { + size_t optab; + enum machine_mode mode1, mode2; + rtx libfunc; +}; + +/* Target-dependent globals. */ +struct GTY(()) target_libfuncs { + /* SYMBOL_REF rtx's for the library functions that are called + implicitly and not via optabs. */ + rtx x_libfunc_table[LTI_MAX]; + + /* Hash table used to convert declarations into nodes. */ + htab_t GTY((param_is (struct libfunc_entry))) x_libfunc_hash; +}; + +extern GTY(()) struct target_libfuncs default_target_libfuncs; +#if SWITCHABLE_TARGET +extern struct target_libfuncs *this_target_libfuncs; +#else +#define this_target_libfuncs (&default_target_libfuncs) +#endif + +#define libfunc_table \ + (this_target_libfuncs->x_libfunc_table) /* Accessor macros for libfunc_table. */ Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2010-07-04 14:18:34.000000000 +0100 +++ gcc/optabs.c 2010-07-04 14:18:38.000000000 +0100 @@ -45,11 +45,14 @@ Software Foundation; either version 3, o #include "target.h" struct target_optabs default_target_optabs; +struct target_libfuncs default_target_libfuncs; #if SWITCHABLE_TARGET struct target_optabs *this_target_optabs; +struct target_libfuncs *this_target_libfuncs; #endif -rtx libfunc_table[LTI_MAX]; +#define libfunc_hash \ + (this_target_libfuncs->x_libfunc_hash) /* Contains the optab used for each rtx code. */ optab code_to_optab[NUM_RTX_CODE + 1]; @@ -68,19 +71,7 @@ #define DECIMAL_PREFIX "bid_" #define DECIMAL_PREFIX "dpd_" #endif - -/* Info about libfunc. We use same hashtable for normal optabs and conversion - optab. In the first case mode2 is unused. */ -struct GTY(()) libfunc_entry { - size_t optab; - enum machine_mode mode1, mode2; - rtx libfunc; -}; - -/* Hash table used to convert declarations into nodes. */ -static GTY((param_is (struct libfunc_entry))) htab_t libfunc_hash; - -/* Used for attribute_hash. */ +/* Used for libfunc_hash. */ static hashval_t hash_libfunc (const void *p) @@ -91,7 +82,7 @@ hash_libfunc (const void *p) ^ e->optab); } -/* Used for optab_hash. */ +/* Used for libfunc_hash. */ static int eq_libfunc (const void *p, const void *q) @@ -6123,14 +6114,15 @@ set_conv_libfunc (convert_optab optable, void init_optabs (void) { - static bool reinit; - - libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL); - - /* We statically initialize the insn_codes with the equivalent of - CODE_FOR_nothing. Repeat the process if reinitialising. */ - if (reinit) - init_insn_codes (); + if (libfunc_hash) + { + htab_empty (libfunc_hash); + /* We statically initialize the insn_codes with the equivalent of + CODE_FOR_nothing. Repeat the process if reinitialising. */ + init_insn_codes (); + } + else + libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL); init_optab (add_optab, PLUS); init_optabv (addv_optab, PLUS); @@ -6571,8 +6563,6 @@ init_optabs (void) /* Allow the target to add more libcalls or rename some, etc. */ targetm.init_libfuncs (); - - reinit = true; } /* Print information about the current contents of the optabs on Index: gcc/target-globals.h =================================================================== --- gcc/target-globals.h 2010-07-04 14:18:34.000000000 +0100 +++ gcc/target-globals.h 2010-07-04 14:18:38.000000000 +0100 @@ -28,6 +28,7 @@ #define TARGET_GLOBALS_H 1 extern struct target_reload *this_target_reload; extern struct target_expmed *this_target_expmed; extern struct target_optabs *this_target_optabs; +extern struct target_libfuncs *this_target_libfuncs; struct GTY(()) target_globals { struct target_flag_state *GTY((skip)) flag_state; @@ -37,6 +38,7 @@ struct GTY(()) target_globals { struct target_reload *GTY((skip)) reload; struct target_expmed *GTY((skip)) expmed; struct target_optabs *GTY((skip)) optabs; + struct target_libfuncs *libfuncs; }; extern struct target_globals default_target_globals; @@ -53,6 +55,7 @@ restore_target_globals (struct target_gl this_target_reload = g->reload; this_target_expmed = g->expmed; this_target_optabs = g->optabs; + this_target_libfuncs = g->libfuncs; } #endif Index: gcc/target-globals.c =================================================================== --- gcc/target-globals.c 2010-07-04 14:18:34.000000000 +0100 +++ gcc/target-globals.c 2010-07-04 14:18:38.000000000 +0100 @@ -34,6 +34,7 @@ Software Foundation; either version 3, o #include "expmed.h" #include "expr.h" #include "optabs.h" +#include "libfuncs.h" #if SWITCHABLE_TARGET struct target_globals default_target_globals = { @@ -43,7 +44,8 @@ struct target_globals default_target_glo &default_target_hard_regs, &default_target_reload, &default_target_expmed, - &default_target_optabs + &default_target_optabs, + &default_target_libfuncs }; struct target_globals * @@ -59,6 +61,7 @@ save_target_globals (void) g->reload = XCNEW (struct target_reload); g->expmed = XCNEW (struct target_expmed); g->optabs = XCNEW (struct target_optabs); + g->libfuncs = ggc_alloc_cleared_target_libfuncs (); restore_target_globals (g); target_reinit (); return g;