summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog27
-rw-r--r--gcc/Makefile.in5
-rw-r--r--gcc/libfuncs.h33
-rw-r--r--gcc/optabs.c40
-rw-r--r--gcc/target-globals.c5
-rw-r--r--gcc/target-globals.h3
6 files changed, 82 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 77a67c6046d..833cfea39c0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,32 @@
2010-07-12 Richard Sandiford <rdsandiford@googlemail.com>
+ * 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.
+
+2010-07-12 Richard Sandiford <rdsandiford@googlemail.com>
+
* Makefile.in (LIBFUNCS_H): New variable. Use instead of libfuncs.h
in all dependency lists.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 4633c40532d..8ee8a32e1e7 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -969,7 +969,7 @@ GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h $(CONFIG_H) $(SYSTEM_H) \
$(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.
@@ -3482,7 +3482,8 @@ lower-subreg.o : lower-subreg.c $(CONFIG_H) $(SYSTEM_H) coretypes.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) $(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 \
diff --git a/gcc/libfuncs.h b/gcc/libfuncs.h
index 9916d2f94f0..68b090eaad1 100644
--- a/gcc/libfuncs.h
+++ b/gcc/libfuncs.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see
#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. */
diff --git a/gcc/optabs.c b/gcc/optabs.c
index e9487d0367e..b9db02fe83f 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -46,11 +46,14 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
struct target_optabs default_target_optabs;
+struct target_libfuncs default_target_libfuncs;
#if SWITCHABLE_TARGET
struct target_optabs *this_target_optabs = &default_target_optabs;
+struct target_libfuncs *this_target_libfuncs = &default_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];
@@ -69,19 +72,7 @@ void debug_optab_libfuncs (void);
#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)
@@ -92,7 +83,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)
@@ -6124,14 +6115,15 @@ set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
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);
@@ -6572,8 +6564,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
diff --git a/gcc/target-globals.c b/gcc/target-globals.c
index cfabb87c909..6655f9a5fe0 100644
--- a/gcc/target-globals.c
+++ b/gcc/target-globals.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#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_globals = {
&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;
diff --git a/gcc/target-globals.h b/gcc/target-globals.h
index a1f4866fb2a..7b7b725f4dc 100644
--- a/gcc/target-globals.h
+++ b/gcc/target-globals.h
@@ -28,6 +28,7 @@ extern struct target_hard_regs *this_target_hard_regs;
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_globals *g)
this_target_reload = g->reload;
this_target_expmed = g->expmed;
this_target_optabs = g->optabs;
+ this_target_libfuncs = g->libfuncs;
}
#endif