From f863a58699d3bfadf18c502e1ee4488e7ebfdd15 Mon Sep 17 00:00:00 2001 From: tbsaunde Date: Thu, 20 Nov 2014 15:10:11 +0000 Subject: [PATCH] implement a replacement for if_marked gcc/ChangeLog: 2014-11-20 Trevor Saunders * doc/gty.texi: Document the new cache gty attribute. * gengtype.c (finish_cache_funcs): New function. (write_roots): Call gt_clear_cache on global variables with the cache gty attribute. * ggc-common.c (ggc_mark_roots): Call gt_clear_caches. * ggc.h (gt_clear_caches): New declaration. * hash-table.h (struct ggc_cache_hasher): New hasher for caches in gc memory. (gt_cleare_cache): New function. * emit-rtl.c, rtl.h, tree.c: Use hash_table instead of htab. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217866 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 13 ++++ gcc/doc/gty.texi | 8 +++ gcc/emit-rtl.c | 178 +++++++++++++++++++++++++++++-------------------------- gcc/gengtype.c | 87 +++++++++++++++++++++++++++ gcc/ggc-common.c | 2 + gcc/ggc.h | 3 + gcc/hash-table.h | 50 ++++++++++++++++ gcc/rtl.h | 2 +- gcc/tree.c | 100 ++++++++++++++----------------- 9 files changed, 302 insertions(+), 141 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f89b08..a27c298 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2014-11-20 Trevor Saunders + + * doc/gty.texi: Document the new cache gty attribute. + * gengtype.c (finish_cache_funcs): New function. + (write_roots): Call gt_clear_cache on global variables with the cache + gty attribute. + * ggc-common.c (ggc_mark_roots): Call gt_clear_caches. + * ggc.h (gt_clear_caches): New declaration. + * hash-table.h (struct ggc_cache_hasher): New hasher for caches in gc + memory. + (gt_cleare_cache): New function. + * emit-rtl.c, rtl.h, tree.c: Use hash_table instead of htab. + 2014-11-20 Segher Boessenkool * combine.c (try_combine): Prefer to delete dead SETs inside diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi index 609cfce..e4d2b60 100644 --- a/gcc/doc/gty.texi +++ b/gcc/doc/gty.texi @@ -293,6 +293,14 @@ the pointed-to structure should use the same parameters as the outer structure. This is done by marking the pointer with the @code{use_params} option. +@findex cache +@item cache + +When the @code{cache} option is applied to a global variable gt_clear_cache is +called on that variable between the mark and sweep phases of garbage +collection. The gt_clear_cache function is free to mark blocks as used, or to +clear pointers in the variable. + @findex deletable @item deletable diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 04f677e..1226aad 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -131,23 +131,50 @@ rtx cc0_rtx; /* A hash table storing CONST_INTs whose absolute value is greater than MAX_SAVED_CONST_INT. */ -static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) - htab_t const_int_htab; +struct const_int_hasher : ggc_cache_hasher +{ + typedef HOST_WIDE_INT compare_type; + + static hashval_t hash (rtx i); + static bool equal (rtx i, HOST_WIDE_INT h); +}; -static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) - htab_t const_wide_int_htab; +static GTY ((cache)) hash_table *const_int_htab; + +struct const_wide_int_hasher : ggc_cache_hasher +{ + static hashval_t hash (rtx x); + static bool equal (rtx x, rtx y); +}; + +static GTY ((cache)) hash_table *const_wide_int_htab; /* A hash table storing register attribute structures. */ -static GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs))) - htab_t reg_attrs_htab; +struct reg_attr_hasher : ggc_cache_hasher +{ + static hashval_t hash (reg_attrs *x); + static bool equal (reg_attrs *a, reg_attrs *b); +}; + +static GTY ((cache)) hash_table *reg_attrs_htab; /* A hash table storing all CONST_DOUBLEs. */ -static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) - htab_t const_double_htab; +struct const_double_hasher : ggc_cache_hasher +{ + static hashval_t hash (rtx x); + static bool equal (rtx x, rtx y); +}; + +static GTY ((cache)) hash_table *const_double_htab; /* A hash table storing all CONST_FIXEDs. */ -static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) - htab_t const_fixed_htab; +struct const_fixed_hasher : ggc_cache_hasher +{ + static hashval_t hash (rtx x); + static bool equal (rtx x, rtx y); +}; + +static GTY ((cache)) hash_table *const_fixed_htab; #define cur_insn_uid (crtl->emit.x_cur_insn_uid) #define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid) @@ -155,21 +182,11 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) static void set_used_decls (tree); static void mark_label_nuses (rtx); -static hashval_t const_int_htab_hash (const void *); -static int const_int_htab_eq (const void *, const void *); #if TARGET_SUPPORTS_WIDE_INT -static hashval_t const_wide_int_htab_hash (const void *); -static int const_wide_int_htab_eq (const void *, const void *); static rtx lookup_const_wide_int (rtx); #endif -static hashval_t const_double_htab_hash (const void *); -static int const_double_htab_eq (const void *, const void *); static rtx lookup_const_double (rtx); -static hashval_t const_fixed_htab_hash (const void *); -static int const_fixed_htab_eq (const void *, const void *); static rtx lookup_const_fixed (rtx); -static hashval_t reg_attrs_htab_hash (const void *); -static int reg_attrs_htab_eq (const void *, const void *); static reg_attrs *get_reg_attrs (tree, int); static rtx gen_const_vector (machine_mode, int); static void copy_rtx_if_shared_1 (rtx *orig); @@ -180,31 +197,31 @@ int split_branch_probability = -1; /* Returns a hash code for X (which is a really a CONST_INT). */ -static hashval_t -const_int_htab_hash (const void *x) +hashval_t +const_int_hasher::hash (rtx x) { - return (hashval_t) INTVAL ((const_rtx) x); + return (hashval_t) INTVAL (x); } /* Returns nonzero if the value represented by X (which is really a CONST_INT) is the same as that given by Y (which is really a HOST_WIDE_INT *). */ -static int -const_int_htab_eq (const void *x, const void *y) +bool +const_int_hasher::equal (rtx x, HOST_WIDE_INT y) { - return (INTVAL ((const_rtx) x) == *((const HOST_WIDE_INT *) y)); + return (INTVAL (x) == y); } #if TARGET_SUPPORTS_WIDE_INT /* Returns a hash code for X (which is a really a CONST_WIDE_INT). */ -static hashval_t -const_wide_int_htab_hash (const void *x) +hashval_t +const_wide_int_hasher::hash (rtx x) { int i; HOST_WIDE_INT hash = 0; - const_rtx xr = (const_rtx) x; + const_rtx xr = x; for (i = 0; i < CONST_WIDE_INT_NUNITS (xr); i++) hash += CONST_WIDE_INT_ELT (xr, i); @@ -216,28 +233,28 @@ const_wide_int_htab_hash (const void *x) CONST_WIDE_INT) is the same as that given by Y (which is really a CONST_WIDE_INT). */ -static int -const_wide_int_htab_eq (const void *x, const void *y) +bool +const_wide_int_hasher::equal (rtx x, rtx y) { int i; - const_rtx xr = (const_rtx) x; - const_rtx yr = (const_rtx) y; + const_rtx xr = x; + const_rtx yr = y; if (CONST_WIDE_INT_NUNITS (xr) != CONST_WIDE_INT_NUNITS (yr)) - return 0; + return false; for (i = 0; i < CONST_WIDE_INT_NUNITS (xr); i++) if (CONST_WIDE_INT_ELT (xr, i) != CONST_WIDE_INT_ELT (yr, i)) - return 0; + return false; - return 1; + return true; } #endif /* Returns a hash code for X (which is really a CONST_DOUBLE). */ -static hashval_t -const_double_htab_hash (const void *x) +hashval_t +const_double_hasher::hash (rtx x) { - const_rtx const value = (const_rtx) x; + const_rtx const value = x; hashval_t h; if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (value) == VOIDmode) @@ -253,10 +270,10 @@ const_double_htab_hash (const void *x) /* Returns nonzero if the value represented by X (really a ...) is the same as that represented by Y (really a ...) */ -static int -const_double_htab_eq (const void *x, const void *y) +bool +const_double_hasher::equal (rtx x, rtx y) { - const_rtx const a = (const_rtx)x, b = (const_rtx)y; + const_rtx const a = x, b = y; if (GET_MODE (a) != GET_MODE (b)) return 0; @@ -270,10 +287,10 @@ const_double_htab_eq (const void *x, const void *y) /* Returns a hash code for X (which is really a CONST_FIXED). */ -static hashval_t -const_fixed_htab_hash (const void *x) +hashval_t +const_fixed_hasher::hash (rtx x) { - const_rtx const value = (const_rtx) x; + const_rtx const value = x; hashval_t h; h = fixed_hash (CONST_FIXED_VALUE (value)); @@ -282,13 +299,13 @@ const_fixed_htab_hash (const void *x) return h; } -/* Returns nonzero if the value represented by X (really a ...) - is the same as that represented by Y (really a ...). */ +/* Returns nonzero if the value represented by X is the same as that + represented by Y. */ -static int -const_fixed_htab_eq (const void *x, const void *y) +bool +const_fixed_hasher::equal (rtx x, rtx y) { - const_rtx const a = (const_rtx) x, b = (const_rtx) y; + const_rtx const a = x, b = y; if (GET_MODE (a) != GET_MODE (b)) return 0; @@ -338,23 +355,22 @@ set_mem_attrs (rtx mem, mem_attrs *attrs) /* Returns a hash code for X (which is a really a reg_attrs *). */ -static hashval_t -reg_attrs_htab_hash (const void *x) +hashval_t +reg_attr_hasher::hash (reg_attrs *x) { - const reg_attrs *const p = (const reg_attrs *) x; + const reg_attrs *const p = x; return ((p->offset * 1000) ^ (intptr_t) p->decl); } -/* Returns nonzero if the value represented by X (which is really a - reg_attrs *) is the same as that given by Y (which is also really a - reg_attrs *). */ +/* Returns nonzero if the value represented by X is the same as that given by + Y. */ -static int -reg_attrs_htab_eq (const void *x, const void *y) +bool +reg_attr_hasher::equal (reg_attrs *x, reg_attrs *y) { - const reg_attrs *const p = (const reg_attrs *) x; - const reg_attrs *const q = (const reg_attrs *) y; + const reg_attrs *const p = x; + const reg_attrs *const q = y; return (p->decl == q->decl && p->offset == q->offset); } @@ -366,7 +382,6 @@ static reg_attrs * get_reg_attrs (tree decl, int offset) { reg_attrs attrs; - void **slot; /* If everything is the default, we can just return zero. */ if (decl == 0 && offset == 0) @@ -375,14 +390,14 @@ get_reg_attrs (tree decl, int offset) attrs.decl = decl; attrs.offset = offset; - slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT); + reg_attrs **slot = reg_attrs_htab->find_slot (&attrs, INSERT); if (*slot == 0) { *slot = ggc_alloc (); memcpy (*slot, &attrs, sizeof (reg_attrs)); } - return (reg_attrs *) *slot; + return *slot; } @@ -444,8 +459,6 @@ gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn, rtx gen_rtx_CONST_INT (machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg) { - void **slot; - if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT) return const_int_rtx[arg + MAX_SAVED_CONST_INT]; @@ -455,12 +468,12 @@ gen_rtx_CONST_INT (machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg) #endif /* Look up the CONST_INT in the hash table. */ - slot = htab_find_slot_with_hash (const_int_htab, &arg, - (hashval_t) arg, INSERT); + rtx *slot = const_int_htab->find_slot_with_hash (arg, (hashval_t) arg, + INSERT); if (*slot == 0) *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg); - return (rtx) *slot; + return *slot; } rtx @@ -479,11 +492,11 @@ gen_int_mode (HOST_WIDE_INT c, machine_mode mode) static rtx lookup_const_double (rtx real) { - void **slot = htab_find_slot (const_double_htab, real, INSERT); + rtx *slot = const_double_htab->find_slot (real, INSERT); if (*slot == 0) *slot = real; - return (rtx) *slot; + return *slot; } /* Return a CONST_DOUBLE rtx for a floating-point value specified by @@ -506,11 +519,11 @@ const_double_from_real_value (REAL_VALUE_TYPE value, machine_mode mode) static rtx lookup_const_fixed (rtx fixed) { - void **slot = htab_find_slot (const_fixed_htab, fixed, INSERT); + rtx *slot = const_fixed_htab->find_slot (fixed, INSERT); if (*slot == 0) *slot = fixed; - return (rtx) *slot; + return *slot; } /* Return a CONST_FIXED rtx for a fixed-point value specified by @@ -557,11 +570,11 @@ rtx_to_double_int (const_rtx cst) static rtx lookup_const_wide_int (rtx wint) { - void **slot = htab_find_slot (const_wide_int_htab, wint, INSERT); + rtx *slot = const_wide_int_htab->find_slot (wint, INSERT); if (*slot == 0) *slot = wint; - return (rtx) *slot; + return *slot; } #endif @@ -5812,7 +5825,7 @@ init_emit_regs (void) mem_attrs *attrs; /* Reset register attributes */ - htab_empty (reg_attrs_htab); + reg_attrs_htab->empty (); /* We need reg_raw_mode, so initialize the modes now. */ init_reg_modes_target (); @@ -5901,21 +5914,16 @@ init_emit_once (void) /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE, CONST_FIXED, and memory attribute hash tables. */ - const_int_htab = htab_create_ggc (37, const_int_htab_hash, - const_int_htab_eq, NULL); + const_int_htab = hash_table::create_ggc (37); #if TARGET_SUPPORTS_WIDE_INT - const_wide_int_htab = htab_create_ggc (37, const_wide_int_htab_hash, - const_wide_int_htab_eq, NULL); + const_wide_int_htab = hash_table::create_ggc (37); #endif - const_double_htab = htab_create_ggc (37, const_double_htab_hash, - const_double_htab_eq, NULL); + const_double_htab = hash_table::create_ggc (37); - const_fixed_htab = htab_create_ggc (37, const_fixed_htab_hash, - const_fixed_htab_eq, NULL); + const_fixed_htab = hash_table::create_ggc (37); - reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash, - reg_attrs_htab_eq, NULL); + reg_attrs_htab = hash_table::create_ggc (37); #ifdef INIT_EXPANDERS /* This is to initialize {init|mark|free}_machine_status before the first diff --git a/gcc/gengtype.c b/gcc/gengtype.c index 71159b0..2dc857e 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -4482,6 +4482,60 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname, } } +/* Finish off the created gt_clear_caches_file_c functions. */ + +static void +finish_cache_funcs (flist *flp) +{ + struct flist *fli2; + + for (fli2 = flp; fli2; fli2 = fli2->next) + if (fli2->started_p) + { + oprintf (fli2->f, "}\n\n"); + } + + for (fli2 = flp; fli2 && base_files; fli2 = fli2->next) + if (fli2->started_p) + { + lang_bitmap bitmap = get_lang_bitmap (fli2->file); + int fnum; + + for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1) + if (bitmap & 1) + { + oprintf (base_files[fnum], "extern void gt_clear_caches_"); + put_mangled_filename (base_files[fnum], fli2->file); + oprintf (base_files[fnum], " ();\n"); + } + } + + for (size_t fnum = 0; base_files && fnum < num_lang_dirs; fnum++) + oprintf (base_files[fnum], "void\ngt_clear_caches ()\n{\n"); + + for (fli2 = flp; fli2; fli2 = fli2->next) + if (fli2->started_p) + { + lang_bitmap bitmap = get_lang_bitmap (fli2->file); + int fnum; + + fli2->started_p = 0; + + for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1) + if (bitmap & 1) + { + oprintf (base_files[fnum], " gt_clear_caches_"); + put_mangled_filename (base_files[fnum], fli2->file); + oprintf (base_files[fnum], " ();\n"); + } + } + + for (size_t fnum = 0; base_files && fnum < num_lang_dirs; fnum++) + { + oprintf (base_files[fnum], "}\n"); + } +} + /* Write the first three fields (pointer, count and stride) for root NAME to F. V and LINE are as for write_root. @@ -4801,6 +4855,8 @@ write_roots (pair_p variables, bool emit_pch) ; else if (strcmp (o->name, "if_marked") == 0) ; + else if (strcmp (o->name, "cache") == 0) + ; else error_at_line (&v->line, "global `%s' has unknown option `%s'", @@ -4952,6 +5008,37 @@ write_roots (pair_p variables, bool emit_pch) finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab", "gt_ggc_cache_rtab"); + for (v = variables; v; v = v->next) + { + outf_p f = get_output_file_with_visibility (CONST_CAST (input_file*, + v->line.file)); + struct flist *fli; + bool cache = false; + options_p o; + + for (o = v->opt; o; o = o->next) + if (strcmp (o->name, "cache") == 0) + cache = true; + if (!cache) + continue; + + for (fli = flp; fli; fli = fli->next) + if (fli->f == f) + break; + if (!fli->started_p) + { + fli->started_p = 1; + + oprintf (f, "void\ngt_clear_caches_"); + put_mangled_filename (f, v->line.file); + oprintf (f, " ()\n{\n"); + } + + oprintf (f, " gt_cleare_cache (%s);\n", v->name); + } + + finish_cache_funcs (flp); + if (!emit_pch) return; diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 32440b4..06f70c2 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -162,6 +162,8 @@ ggc_mark_roots (void) for (ct = gt_ggc_cache_rtab; *ct; ct++) ggc_scan_cache_tab (*ct); + gt_clear_caches (); + FOR_EACH_VEC_ELT (extra_cache_vec, i, ctp) ggc_scan_cache_tab (ctp); diff --git a/gcc/ggc.h b/gcc/ggc.h index dc21520..fb8ce73 100644 --- a/gcc/ggc.h +++ b/gcc/ggc.h @@ -54,6 +54,9 @@ extern int gt_pch_note_object (void *, void *, gt_note_pointers); function. */ extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder); +/* generated function to clear caches in gc memory. */ +extern void gt_clear_caches (); + /* Mark the object in the first parameter and anything it points to. */ typedef void (*gt_pointer_walker) (void *); diff --git a/gcc/hash-table.h b/gcc/hash-table.h index 2493f2e..a6f66c0 100644 --- a/gcc/hash-table.h +++ b/gcc/hash-table.h @@ -334,6 +334,44 @@ struct ggc_hasher } }; +/* Hasher for cache entry in gc memory. */ + +template +struct ggc_cache_hasher +{ + typedef T value_type; + typedef T compare_type; + typedef int store_values_directly; + + static void remove (T &) {} + + /* Entries are weakly held because this is for caches. */ + + static void ggc_mx (T &) {} + + static void + pch_nx (T &p) + { + extern void gt_pch_nx (T &); + gt_pch_nx (p); + } + + static void + pch_nx (T &p, gt_pointer_operator op, void *cookie) + { + op (&p, cookie); + } + + /* Clear out entries if they are about to be gc'd. */ + + static void + handle_cache_entry (T &e) + { + if (e != HTAB_EMPTY_ENTRY && e != HTAB_DELETED_ENTRY && !ggc_marked_p (e)) + e = static_cast (HTAB_DELETED_ENTRY); + } +}; + /* Table of primes and their inversion information. */ @@ -1667,4 +1705,16 @@ gt_pch_nx (hash_table *h, gt_pointer_operator op, void *cookie) op (&h->m_entries, cookie); } +template +inline void +gt_cleare_cache (hash_table *h) +{ + if (!h) + return; + + for (typename hash_table::iterator iter = h->begin (); iter != h->end (); + ++iter) + H::handle_cache_entry (*iter); +} + #endif /* TYPED_HASHTAB_H */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 3bfb6bf..b9d62ae 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -181,7 +181,7 @@ struct GTY(()) mem_attrs object in the low part of a 4-byte register, the OFFSET field will be -3 rather than 0. */ -struct GTY(()) reg_attrs { +struct GTY((for_user)) reg_attrs { tree decl; /* decl corresponding to REG. */ HOST_WIDE_INT offset; /* Offset from start of DECL. */ }; diff --git a/gcc/tree.c b/gcc/tree.c index 6abe4c3..35d2ad8 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -205,8 +205,14 @@ static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash))) /* Hash table and temporary node for larger integer const values. */ static GTY (()) tree int_cst_node; -static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node))) - htab_t int_cst_hash_table; + +struct int_cst_hasher : ggc_cache_hasher +{ + static hashval_t hash (tree t); + static bool equal (tree x, tree y); +}; + +static GTY ((cache)) hash_table *int_cst_hash_table; /* Hash table for optimization flags and target option flags. Use the same hash table for both sets of options. Nodes for building the current @@ -215,8 +221,14 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node))) allocating and freeing up a node repeatably. */ static GTY (()) tree cl_optimization_node; static GTY (()) tree cl_target_option_node; -static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node))) - htab_t cl_option_hash_table; + +struct cl_option_hasher : ggc_cache_hasher +{ + static hashval_t hash (tree t); + static bool equal (tree x, tree y); +}; + +static GTY ((cache)) hash_table *cl_option_hash_table; /* General tree->tree mapping structure for use in hash tables. */ @@ -233,10 +245,6 @@ static GTY ((if_marked ("tree_vec_map_marked_p"), param_is (struct tree_vec_map) static void set_type_quals (tree, int); static int type_hash_eq (const void *, const void *); static hashval_t type_hash_hash (const void *); -static hashval_t int_cst_hash_hash (const void *); -static int int_cst_hash_eq (const void *, const void *); -static hashval_t cl_option_hash_hash (const void *); -static int cl_option_hash_eq (const void *, const void *); static void print_type_hash_statistics (void); static void print_debug_expr_statistics (void); static void print_value_expr_statistics (void); @@ -585,13 +593,11 @@ init_ttree (void) value_expr_for_decl = htab_create_ggc (512, tree_decl_map_hash, tree_decl_map_eq, 0); - int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash, - int_cst_hash_eq, NULL); + int_cst_hash_table = hash_table::create_ggc (1024); int_cst_node = make_int_cst (1, 1); - cl_option_hash_table = htab_create_ggc (64, cl_option_hash_hash, - cl_option_hash_eq, NULL); + cl_option_hash_table = hash_table::create_ggc (64); cl_optimization_node = make_node (OPTIMIZATION_NODE); cl_target_option_node = make_node (TARGET_OPTION_NODE); @@ -1256,10 +1262,10 @@ force_fit_type (tree type, const wide_int_ref &cst, /* Return the hash code code X, an INTEGER_CST. */ -static hashval_t -int_cst_hash_hash (const void *x) +hashval_t +int_cst_hasher::hash (tree x) { - const_tree const t = (const_tree) x; + const_tree const t = x; hashval_t code = htab_hash_pointer (TREE_TYPE (t)); int i; @@ -1272,11 +1278,11 @@ int_cst_hash_hash (const void *x) /* Return nonzero if the value represented by *X (an INTEGER_CST tree node) is the same as that given by *Y, which is the same. */ -static int -int_cst_hash_eq (const void *x, const void *y) +bool +int_cst_hasher::equal (tree x, tree y) { - const_tree const xt = (const_tree) x; - const_tree const yt = (const_tree) y; + const_tree const xt = x; + const_tree const yt = y; if (TREE_TYPE (xt) != TREE_TYPE (yt) || TREE_INT_CST_NUNITS (xt) != TREE_INT_CST_NUNITS (yt) @@ -1408,13 +1414,12 @@ wide_int_to_tree (tree type, const wide_int_ref &pcst) { /* Use the cache of larger shared ints, using int_cst_node as a temporary. */ - void **slot; TREE_INT_CST_ELT (int_cst_node, 0) = hwi; TREE_TYPE (int_cst_node) = type; - slot = htab_find_slot (int_cst_hash_table, int_cst_node, INSERT); - t = (tree) *slot; + tree *slot = int_cst_hash_table->find_slot (int_cst_node, INSERT); + t = *slot; if (!t) { /* Insert this one into the hash table. */ @@ -1430,11 +1435,10 @@ wide_int_to_tree (tree type, const wide_int_ref &pcst) /* The value either hashes properly or we drop it on the floor for the gc to take care of. There will not be enough of them to worry about. */ - void **slot; tree nt = build_new_int_cst (type, cst); - slot = htab_find_slot (int_cst_hash_table, nt, INSERT); - t = (tree) *slot; + tree *slot = int_cst_hash_table->find_slot (nt, INSERT); + t = *slot; if (!t) { /* Insert this one into the hash table. */ @@ -1539,9 +1543,7 @@ cache_integer_cst (tree t) else { /* Use the cache of larger shared ints. */ - void **slot; - - slot = htab_find_slot (int_cst_hash_table, t, INSERT); + tree *slot = int_cst_hash_table->find_slot (t, INSERT); /* If there is already an entry for the number verify it's the same. */ if (*slot) @@ -11498,10 +11500,10 @@ tree_nonartificial_location (tree exp) /* Return the hash code code X, an OPTIMIZATION_NODE or TARGET_OPTION code. */ -static hashval_t -cl_option_hash_hash (const void *x) +hashval_t +cl_option_hasher::hash (tree x) { - const_tree const t = (const_tree) x; + const_tree const t = x; const char *p; size_t i; size_t len = 0; @@ -11532,11 +11534,11 @@ cl_option_hash_hash (const void *x) TARGET_OPTION tree node) is the same as that given by *Y, which is the same. */ -static int -cl_option_hash_eq (const void *x, const void *y) +bool +cl_option_hasher::equal (tree x, tree y) { - const_tree const xt = (const_tree) x; - const_tree const yt = (const_tree) y; + const_tree const xt = x; + const_tree const yt = y; const char *xp; const char *yp; size_t len; @@ -11569,15 +11571,14 @@ tree build_optimization_node (struct gcc_options *opts) { tree t; - void **slot; /* Use the cache of optimization nodes. */ cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node), opts); - slot = htab_find_slot (cl_option_hash_table, cl_optimization_node, INSERT); - t = (tree) *slot; + tree *slot = cl_option_hash_table->find_slot (cl_optimization_node, INSERT); + t = *slot; if (!t) { /* Insert this one into the hash table. */ @@ -11597,15 +11598,14 @@ tree build_target_option_node (struct gcc_options *opts) { tree t; - void **slot; /* Use the cache of optimization nodes. */ cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node), opts); - slot = htab_find_slot (cl_option_hash_table, cl_target_option_node, INSERT); - t = (tree) *slot; + tree *slot = cl_option_hash_table->find_slot (cl_target_option_node, INSERT); + t = *slot; if (!t) { /* Insert this one into the hash table. */ @@ -11619,26 +11619,16 @@ build_target_option_node (struct gcc_options *opts) return t; } -/* Reset TREE_TARGET_GLOBALS cache for TARGET_OPTION_NODE. - Called through htab_traverse. */ - -static int -prepare_target_option_node_for_pch (void **slot, void *) -{ - tree node = (tree) *slot; - if (TREE_CODE (node) == TARGET_OPTION_NODE) - TREE_TARGET_GLOBALS (node) = NULL; - return 1; -} - /* Clear TREE_TARGET_GLOBALS of all TARGET_OPTION_NODE trees, so that they aren't saved during PCH writing. */ void prepare_target_option_nodes_for_pch (void) { - htab_traverse (cl_option_hash_table, prepare_target_option_node_for_pch, - NULL); + hash_table::iterator iter = cl_option_hash_table->begin (); + for (; iter != cl_option_hash_table->end (); ++iter) + if (TREE_CODE (*iter) == TARGET_OPTION_NODE) + TREE_TARGET_GLOBALS (*iter) = NULL; } /* Determine the "ultimate origin" of a block. The block may be an inlined -- 2.7.4