Patchwork [15/27] Use target structures for libfuncs

login
register
mail settings
Submitter Richard Sandiford
Date July 7, 2010, 9:07 p.m.
Message ID <87aaq3t2zk.fsf@firetop.home>
Download mbox | patch
Permalink /patch/58180/
State New
Headers show

Comments

Richard Sandiford - July 7, 2010, 9:07 p.m.
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.

Patch

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;