Commit aebf76a2 by Trevor Saunders Committed by Trevor Saunders

implement a replacement for if_marked

gcc/ChangeLog:

2014-11-20  Trevor Saunders  <tsaunders@mozilla.com>

	* 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.

From-SVN: r217866
parent 77486f44
2014-11-20 Trevor Saunders <tsaunders@mozilla.com>
* 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 <segher@kernel.crashing.org> 2014-11-20 Segher Boessenkool <segher@kernel.crashing.org>
* combine.c (try_combine): Prefer to delete dead SETs inside * combine.c (try_combine): Prefer to delete dead SETs inside
...@@ -293,6 +293,14 @@ the pointed-to structure should use the same parameters as the outer ...@@ -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 structure. This is done by marking the pointer with the
@code{use_params} option. @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 @findex deletable
@item deletable @item deletable
......
...@@ -131,23 +131,50 @@ rtx cc0_rtx; ...@@ -131,23 +131,50 @@ rtx cc0_rtx;
/* A hash table storing CONST_INTs whose absolute value is greater /* A hash table storing CONST_INTs whose absolute value is greater
than MAX_SAVED_CONST_INT. */ than MAX_SAVED_CONST_INT. */
static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) struct const_int_hasher : ggc_cache_hasher<rtx>
htab_t const_int_htab; {
typedef HOST_WIDE_INT compare_type;
static hashval_t hash (rtx i);
static bool equal (rtx i, HOST_WIDE_INT h);
};
static GTY ((cache)) hash_table<const_int_hasher> *const_int_htab;
struct const_wide_int_hasher : ggc_cache_hasher<rtx>
{
static hashval_t hash (rtx x);
static bool equal (rtx x, rtx y);
};
static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) static GTY ((cache)) hash_table<const_wide_int_hasher> *const_wide_int_htab;
htab_t const_wide_int_htab;
/* A hash table storing register attribute structures. */ /* A hash table storing register attribute structures. */
static GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs))) struct reg_attr_hasher : ggc_cache_hasher<reg_attrs *>
htab_t reg_attrs_htab; {
static hashval_t hash (reg_attrs *x);
static bool equal (reg_attrs *a, reg_attrs *b);
};
static GTY ((cache)) hash_table<reg_attr_hasher> *reg_attrs_htab;
/* A hash table storing all CONST_DOUBLEs. */ /* A hash table storing all CONST_DOUBLEs. */
static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) struct const_double_hasher : ggc_cache_hasher<rtx>
htab_t const_double_htab; {
static hashval_t hash (rtx x);
static bool equal (rtx x, rtx y);
};
static GTY ((cache)) hash_table<const_double_hasher> *const_double_htab;
/* A hash table storing all CONST_FIXEDs. */ /* A hash table storing all CONST_FIXEDs. */
static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) struct const_fixed_hasher : ggc_cache_hasher<rtx>
htab_t const_fixed_htab; {
static hashval_t hash (rtx x);
static bool equal (rtx x, rtx y);
};
static GTY ((cache)) hash_table<const_fixed_hasher> *const_fixed_htab;
#define cur_insn_uid (crtl->emit.x_cur_insn_uid) #define cur_insn_uid (crtl->emit.x_cur_insn_uid)
#define cur_debug_insn_uid (crtl->emit.x_cur_debug_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))) ...@@ -155,21 +182,11 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
static void set_used_decls (tree); static void set_used_decls (tree);
static void mark_label_nuses (rtx); 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 #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); static rtx lookup_const_wide_int (rtx);
#endif #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 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 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 reg_attrs *get_reg_attrs (tree, int);
static rtx gen_const_vector (machine_mode, int); static rtx gen_const_vector (machine_mode, int);
static void copy_rtx_if_shared_1 (rtx *orig); static void copy_rtx_if_shared_1 (rtx *orig);
...@@ -180,31 +197,31 @@ int split_branch_probability = -1; ...@@ -180,31 +197,31 @@ int split_branch_probability = -1;
/* Returns a hash code for X (which is a really a CONST_INT). */ /* Returns a hash code for X (which is a really a CONST_INT). */
static hashval_t hashval_t
const_int_htab_hash (const void *x) 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 /* 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 CONST_INT) is the same as that given by Y (which is really a
HOST_WIDE_INT *). */ HOST_WIDE_INT *). */
static int bool
const_int_htab_eq (const void *x, const void *y) 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 #if TARGET_SUPPORTS_WIDE_INT
/* Returns a hash code for X (which is a really a CONST_WIDE_INT). */ /* Returns a hash code for X (which is a really a CONST_WIDE_INT). */
static hashval_t hashval_t
const_wide_int_htab_hash (const void *x) const_wide_int_hasher::hash (rtx x)
{ {
int i; int i;
HOST_WIDE_INT hash = 0; 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++) for (i = 0; i < CONST_WIDE_INT_NUNITS (xr); i++)
hash += CONST_WIDE_INT_ELT (xr, i); hash += CONST_WIDE_INT_ELT (xr, i);
...@@ -216,28 +233,28 @@ const_wide_int_htab_hash (const void *x) ...@@ -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) is the same as that given by Y (which is really a
CONST_WIDE_INT). */ CONST_WIDE_INT). */
static int bool
const_wide_int_htab_eq (const void *x, const void *y) const_wide_int_hasher::equal (rtx x, rtx y)
{ {
int i; int i;
const_rtx xr = (const_rtx) x; const_rtx xr = x;
const_rtx yr = (const_rtx) y; const_rtx yr = y;
if (CONST_WIDE_INT_NUNITS (xr) != CONST_WIDE_INT_NUNITS (yr)) 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++) for (i = 0; i < CONST_WIDE_INT_NUNITS (xr); i++)
if (CONST_WIDE_INT_ELT (xr, i) != CONST_WIDE_INT_ELT (yr, i)) if (CONST_WIDE_INT_ELT (xr, i) != CONST_WIDE_INT_ELT (yr, i))
return 0; return false;
return 1; return true;
} }
#endif #endif
/* Returns a hash code for X (which is really a CONST_DOUBLE). */ /* Returns a hash code for X (which is really a CONST_DOUBLE). */
static hashval_t hashval_t
const_double_htab_hash (const void *x) const_double_hasher::hash (rtx x)
{ {
const_rtx const value = (const_rtx) x; const_rtx const value = x;
hashval_t h; hashval_t h;
if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (value) == VOIDmode) if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (value) == VOIDmode)
...@@ -253,10 +270,10 @@ const_double_htab_hash (const void *x) ...@@ -253,10 +270,10 @@ const_double_htab_hash (const void *x)
/* Returns nonzero if the value represented by X (really a ...) /* Returns nonzero if the value represented by X (really a ...)
is the same as that represented by Y (really a ...) */ is the same as that represented by Y (really a ...) */
static int bool
const_double_htab_eq (const void *x, const void *y) 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)) if (GET_MODE (a) != GET_MODE (b))
return 0; return 0;
...@@ -270,10 +287,10 @@ const_double_htab_eq (const void *x, const void *y) ...@@ -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). */ /* Returns a hash code for X (which is really a CONST_FIXED). */
static hashval_t hashval_t
const_fixed_htab_hash (const void *x) const_fixed_hasher::hash (rtx x)
{ {
const_rtx const value = (const_rtx) x; const_rtx const value = x;
hashval_t h; hashval_t h;
h = fixed_hash (CONST_FIXED_VALUE (value)); h = fixed_hash (CONST_FIXED_VALUE (value));
...@@ -282,13 +299,13 @@ const_fixed_htab_hash (const void *x) ...@@ -282,13 +299,13 @@ const_fixed_htab_hash (const void *x)
return h; return h;
} }
/* Returns nonzero if the value represented by X (really a ...) /* Returns nonzero if the value represented by X is the same as that
is the same as that represented by Y (really a ...). */ represented by Y. */
static int bool
const_fixed_htab_eq (const void *x, const void *y) 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)) if (GET_MODE (a) != GET_MODE (b))
return 0; return 0;
...@@ -338,23 +355,22 @@ set_mem_attrs (rtx mem, mem_attrs *attrs) ...@@ -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 *). */ /* Returns a hash code for X (which is a really a reg_attrs *). */
static hashval_t hashval_t
reg_attrs_htab_hash (const void *x) 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); return ((p->offset * 1000) ^ (intptr_t) p->decl);
} }
/* Returns nonzero if the value represented by X (which is really a /* Returns nonzero if the value represented by X is the same as that given by
reg_attrs *) is the same as that given by Y (which is also really a Y. */
reg_attrs *). */
static int bool
reg_attrs_htab_eq (const void *x, const void *y) reg_attr_hasher::equal (reg_attrs *x, reg_attrs *y)
{ {
const reg_attrs *const p = (const reg_attrs *) x; const reg_attrs *const p = x;
const reg_attrs *const q = (const reg_attrs *) y; const reg_attrs *const q = y;
return (p->decl == q->decl && p->offset == q->offset); return (p->decl == q->decl && p->offset == q->offset);
} }
...@@ -366,7 +382,6 @@ static reg_attrs * ...@@ -366,7 +382,6 @@ static reg_attrs *
get_reg_attrs (tree decl, int offset) get_reg_attrs (tree decl, int offset)
{ {
reg_attrs attrs; reg_attrs attrs;
void **slot;
/* If everything is the default, we can just return zero. */ /* If everything is the default, we can just return zero. */
if (decl == 0 && offset == 0) if (decl == 0 && offset == 0)
...@@ -375,14 +390,14 @@ get_reg_attrs (tree decl, int offset) ...@@ -375,14 +390,14 @@ get_reg_attrs (tree decl, int offset)
attrs.decl = decl; attrs.decl = decl;
attrs.offset = offset; 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) if (*slot == 0)
{ {
*slot = ggc_alloc<reg_attrs> (); *slot = ggc_alloc<reg_attrs> ();
memcpy (*slot, &attrs, sizeof (reg_attrs)); 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, ...@@ -444,8 +459,6 @@ gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn,
rtx rtx
gen_rtx_CONST_INT (machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg) 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) if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
return const_int_rtx[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) ...@@ -455,12 +468,12 @@ gen_rtx_CONST_INT (machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)
#endif #endif
/* Look up the CONST_INT in the hash table. */ /* Look up the CONST_INT in the hash table. */
slot = htab_find_slot_with_hash (const_int_htab, &arg, rtx *slot = const_int_htab->find_slot_with_hash (arg, (hashval_t) arg,
(hashval_t) arg, INSERT); INSERT);
if (*slot == 0) if (*slot == 0)
*slot = gen_rtx_raw_CONST_INT (VOIDmode, arg); *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);
return (rtx) *slot; return *slot;
} }
rtx rtx
...@@ -479,11 +492,11 @@ gen_int_mode (HOST_WIDE_INT c, machine_mode mode) ...@@ -479,11 +492,11 @@ gen_int_mode (HOST_WIDE_INT c, machine_mode mode)
static rtx static rtx
lookup_const_double (rtx real) 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) if (*slot == 0)
*slot = real; *slot = real;
return (rtx) *slot; return *slot;
} }
/* Return a CONST_DOUBLE rtx for a floating-point value specified by /* 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) ...@@ -506,11 +519,11 @@ const_double_from_real_value (REAL_VALUE_TYPE value, machine_mode mode)
static rtx static rtx
lookup_const_fixed (rtx fixed) 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) if (*slot == 0)
*slot = fixed; *slot = fixed;
return (rtx) *slot; return *slot;
} }
/* Return a CONST_FIXED rtx for a fixed-point value specified by /* Return a CONST_FIXED rtx for a fixed-point value specified by
...@@ -557,11 +570,11 @@ rtx_to_double_int (const_rtx cst) ...@@ -557,11 +570,11 @@ rtx_to_double_int (const_rtx cst)
static rtx static rtx
lookup_const_wide_int (rtx wint) 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) if (*slot == 0)
*slot = wint; *slot = wint;
return (rtx) *slot; return *slot;
} }
#endif #endif
...@@ -5812,7 +5825,7 @@ init_emit_regs (void) ...@@ -5812,7 +5825,7 @@ init_emit_regs (void)
mem_attrs *attrs; mem_attrs *attrs;
/* Reset register attributes */ /* Reset register attributes */
htab_empty (reg_attrs_htab); reg_attrs_htab->empty ();
/* We need reg_raw_mode, so initialize the modes now. */ /* We need reg_raw_mode, so initialize the modes now. */
init_reg_modes_target (); init_reg_modes_target ();
...@@ -5901,21 +5914,16 @@ init_emit_once (void) ...@@ -5901,21 +5914,16 @@ init_emit_once (void)
/* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE, /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE,
CONST_FIXED, and memory attribute hash tables. */ CONST_FIXED, and memory attribute hash tables. */
const_int_htab = htab_create_ggc (37, const_int_htab_hash, const_int_htab = hash_table<const_int_hasher>::create_ggc (37);
const_int_htab_eq, NULL);
#if TARGET_SUPPORTS_WIDE_INT #if TARGET_SUPPORTS_WIDE_INT
const_wide_int_htab = htab_create_ggc (37, const_wide_int_htab_hash, const_wide_int_htab = hash_table<const_wide_int_hasher>::create_ggc (37);
const_wide_int_htab_eq, NULL);
#endif #endif
const_double_htab = htab_create_ggc (37, const_double_htab_hash, const_double_htab = hash_table<const_double_hasher>::create_ggc (37);
const_double_htab_eq, NULL);
const_fixed_htab = htab_create_ggc (37, const_fixed_htab_hash, const_fixed_htab = hash_table<const_fixed_hasher>::create_ggc (37);
const_fixed_htab_eq, NULL);
reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash, reg_attrs_htab = hash_table<reg_attr_hasher>::create_ggc (37);
reg_attrs_htab_eq, NULL);
#ifdef INIT_EXPANDERS #ifdef INIT_EXPANDERS
/* This is to initialize {init|mark|free}_machine_status before the first /* This is to initialize {init|mark|free}_machine_status before the first
......
...@@ -4482,6 +4482,60 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname, ...@@ -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 /* Write the first three fields (pointer, count and stride) for
root NAME to F. V and LINE are as for write_root. root NAME to F. V and LINE are as for write_root.
...@@ -4801,6 +4855,8 @@ write_roots (pair_p variables, bool emit_pch) ...@@ -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, "if_marked") == 0)
; ;
else if (strcmp (o->name, "cache") == 0)
;
else else
error_at_line (&v->line, error_at_line (&v->line,
"global `%s' has unknown option `%s'", "global `%s' has unknown option `%s'",
...@@ -4952,6 +5008,37 @@ write_roots (pair_p variables, bool emit_pch) ...@@ -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", finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
"gt_ggc_cache_rtab"); "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) if (!emit_pch)
return; return;
......
...@@ -162,6 +162,8 @@ ggc_mark_roots (void) ...@@ -162,6 +162,8 @@ ggc_mark_roots (void)
for (ct = gt_ggc_cache_rtab; *ct; ct++) for (ct = gt_ggc_cache_rtab; *ct; ct++)
ggc_scan_cache_tab (*ct); ggc_scan_cache_tab (*ct);
gt_clear_caches ();
FOR_EACH_VEC_ELT (extra_cache_vec, i, ctp) FOR_EACH_VEC_ELT (extra_cache_vec, i, ctp)
ggc_scan_cache_tab (ctp); ggc_scan_cache_tab (ctp);
......
...@@ -54,6 +54,9 @@ extern int gt_pch_note_object (void *, void *, gt_note_pointers); ...@@ -54,6 +54,9 @@ extern int gt_pch_note_object (void *, void *, gt_note_pointers);
function. */ function. */
extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder); 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. */ /* Mark the object in the first parameter and anything it points to. */
typedef void (*gt_pointer_walker) (void *); typedef void (*gt_pointer_walker) (void *);
......
...@@ -334,6 +334,44 @@ struct ggc_hasher ...@@ -334,6 +334,44 @@ struct ggc_hasher
} }
}; };
/* Hasher for cache entry in gc memory. */
template<typename T>
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<T> (HTAB_DELETED_ENTRY);
}
};
/* Table of primes and their inversion information. */ /* Table of primes and their inversion information. */
...@@ -1667,4 +1705,16 @@ gt_pch_nx (hash_table<D> *h, gt_pointer_operator op, void *cookie) ...@@ -1667,4 +1705,16 @@ gt_pch_nx (hash_table<D> *h, gt_pointer_operator op, void *cookie)
op (&h->m_entries, cookie); op (&h->m_entries, cookie);
} }
template<typename H>
inline void
gt_cleare_cache (hash_table<H> *h)
{
if (!h)
return;
for (typename hash_table<H>::iterator iter = h->begin (); iter != h->end ();
++iter)
H::handle_cache_entry (*iter);
}
#endif /* TYPED_HASHTAB_H */ #endif /* TYPED_HASHTAB_H */
...@@ -181,7 +181,7 @@ struct GTY(()) mem_attrs ...@@ -181,7 +181,7 @@ struct GTY(()) mem_attrs
object in the low part of a 4-byte register, the OFFSET field object in the low part of a 4-byte register, the OFFSET field
will be -3 rather than 0. */ will be -3 rather than 0. */
struct GTY(()) reg_attrs { struct GTY((for_user)) reg_attrs {
tree decl; /* decl corresponding to REG. */ tree decl; /* decl corresponding to REG. */
HOST_WIDE_INT offset; /* Offset from start of DECL. */ HOST_WIDE_INT offset; /* Offset from start of DECL. */
}; };
......
...@@ -205,8 +205,14 @@ static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash))) ...@@ -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. */ /* Hash table and temporary node for larger integer const values. */
static GTY (()) tree int_cst_node; 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<tree>
{
static hashval_t hash (tree t);
static bool equal (tree x, tree y);
};
static GTY ((cache)) hash_table<int_cst_hasher> *int_cst_hash_table;
/* Hash table for optimization flags and target option flags. Use the same /* Hash table for optimization flags and target option flags. Use the same
hash table for both sets of options. Nodes for building the current 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))) ...@@ -215,8 +221,14 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
allocating and freeing up a node repeatably. */ allocating and freeing up a node repeatably. */
static GTY (()) tree cl_optimization_node; static GTY (()) tree cl_optimization_node;
static GTY (()) tree cl_target_option_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<tree>
{
static hashval_t hash (tree t);
static bool equal (tree x, tree y);
};
static GTY ((cache)) hash_table<cl_option_hasher> *cl_option_hash_table;
/* General tree->tree mapping structure for use in hash tables. */ /* 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) ...@@ -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 void set_type_quals (tree, int);
static int type_hash_eq (const void *, const void *); static int type_hash_eq (const void *, const void *);
static hashval_t type_hash_hash (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_type_hash_statistics (void);
static void print_debug_expr_statistics (void); static void print_debug_expr_statistics (void);
static void print_value_expr_statistics (void); static void print_value_expr_statistics (void);
...@@ -585,13 +593,11 @@ init_ttree (void) ...@@ -585,13 +593,11 @@ init_ttree (void)
value_expr_for_decl = htab_create_ggc (512, tree_decl_map_hash, value_expr_for_decl = htab_create_ggc (512, tree_decl_map_hash,
tree_decl_map_eq, 0); tree_decl_map_eq, 0);
int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash, int_cst_hash_table = hash_table<int_cst_hasher>::create_ggc (1024);
int_cst_hash_eq, NULL);
int_cst_node = make_int_cst (1, 1); int_cst_node = make_int_cst (1, 1);
cl_option_hash_table = htab_create_ggc (64, cl_option_hash_hash, cl_option_hash_table = hash_table<cl_option_hasher>::create_ggc (64);
cl_option_hash_eq, NULL);
cl_optimization_node = make_node (OPTIMIZATION_NODE); cl_optimization_node = make_node (OPTIMIZATION_NODE);
cl_target_option_node = make_node (TARGET_OPTION_NODE); cl_target_option_node = make_node (TARGET_OPTION_NODE);
...@@ -1256,10 +1262,10 @@ force_fit_type (tree type, const wide_int_ref &cst, ...@@ -1256,10 +1262,10 @@ force_fit_type (tree type, const wide_int_ref &cst,
/* Return the hash code code X, an INTEGER_CST. */ /* Return the hash code code X, an INTEGER_CST. */
static hashval_t hashval_t
int_cst_hash_hash (const void *x) 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)); hashval_t code = htab_hash_pointer (TREE_TYPE (t));
int i; int i;
...@@ -1272,11 +1278,11 @@ int_cst_hash_hash (const void *x) ...@@ -1272,11 +1278,11 @@ int_cst_hash_hash (const void *x)
/* Return nonzero if the value represented by *X (an INTEGER_CST tree node) /* 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. */ is the same as that given by *Y, which is the same. */
static int bool
int_cst_hash_eq (const void *x, const void *y) int_cst_hasher::equal (tree x, tree y)
{ {
const_tree const xt = (const_tree) x; const_tree const xt = x;
const_tree const yt = (const_tree) y; const_tree const yt = y;
if (TREE_TYPE (xt) != TREE_TYPE (yt) if (TREE_TYPE (xt) != TREE_TYPE (yt)
|| TREE_INT_CST_NUNITS (xt) != TREE_INT_CST_NUNITS (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) ...@@ -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 /* Use the cache of larger shared ints, using int_cst_node as
a temporary. */ a temporary. */
void **slot;
TREE_INT_CST_ELT (int_cst_node, 0) = hwi; TREE_INT_CST_ELT (int_cst_node, 0) = hwi;
TREE_TYPE (int_cst_node) = type; TREE_TYPE (int_cst_node) = type;
slot = htab_find_slot (int_cst_hash_table, int_cst_node, INSERT); tree *slot = int_cst_hash_table->find_slot (int_cst_node, INSERT);
t = (tree) *slot; t = *slot;
if (!t) if (!t)
{ {
/* Insert this one into the hash table. */ /* Insert this one into the hash table. */
...@@ -1430,11 +1435,10 @@ wide_int_to_tree (tree type, const wide_int_ref &pcst) ...@@ -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 /* 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 for the gc to take care of. There will not be enough of them
to worry about. */ to worry about. */
void **slot;
tree nt = build_new_int_cst (type, cst); tree nt = build_new_int_cst (type, cst);
slot = htab_find_slot (int_cst_hash_table, nt, INSERT); tree *slot = int_cst_hash_table->find_slot (nt, INSERT);
t = (tree) *slot; t = *slot;
if (!t) if (!t)
{ {
/* Insert this one into the hash table. */ /* Insert this one into the hash table. */
...@@ -1539,9 +1543,7 @@ cache_integer_cst (tree t) ...@@ -1539,9 +1543,7 @@ cache_integer_cst (tree t)
else else
{ {
/* Use the cache of larger shared ints. */ /* Use the cache of larger shared ints. */
void **slot; tree *slot = int_cst_hash_table->find_slot (t, INSERT);
slot = htab_find_slot (int_cst_hash_table, t, INSERT);
/* If there is already an entry for the number verify it's the /* If there is already an entry for the number verify it's the
same. */ same. */
if (*slot) if (*slot)
...@@ -11498,10 +11500,10 @@ tree_nonartificial_location (tree exp) ...@@ -11498,10 +11500,10 @@ tree_nonartificial_location (tree exp)
/* Return the hash code code X, an OPTIMIZATION_NODE or TARGET_OPTION code. */ /* Return the hash code code X, an OPTIMIZATION_NODE or TARGET_OPTION code. */
static hashval_t hashval_t
cl_option_hash_hash (const void *x) cl_option_hasher::hash (tree x)
{ {
const_tree const t = (const_tree) x; const_tree const t = x;
const char *p; const char *p;
size_t i; size_t i;
size_t len = 0; size_t len = 0;
...@@ -11532,11 +11534,11 @@ cl_option_hash_hash (const void *x) ...@@ -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 TARGET_OPTION tree node) is the same as that given by *Y, which is the
same. */ same. */
static int bool
cl_option_hash_eq (const void *x, const void *y) cl_option_hasher::equal (tree x, tree y)
{ {
const_tree const xt = (const_tree) x; const_tree const xt = x;
const_tree const yt = (const_tree) y; const_tree const yt = y;
const char *xp; const char *xp;
const char *yp; const char *yp;
size_t len; size_t len;
...@@ -11569,15 +11571,14 @@ tree ...@@ -11569,15 +11571,14 @@ tree
build_optimization_node (struct gcc_options *opts) build_optimization_node (struct gcc_options *opts)
{ {
tree t; tree t;
void **slot;
/* Use the cache of optimization nodes. */ /* Use the cache of optimization nodes. */
cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node), cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node),
opts); opts);
slot = htab_find_slot (cl_option_hash_table, cl_optimization_node, INSERT); tree *slot = cl_option_hash_table->find_slot (cl_optimization_node, INSERT);
t = (tree) *slot; t = *slot;
if (!t) if (!t)
{ {
/* Insert this one into the hash table. */ /* Insert this one into the hash table. */
...@@ -11597,15 +11598,14 @@ tree ...@@ -11597,15 +11598,14 @@ tree
build_target_option_node (struct gcc_options *opts) build_target_option_node (struct gcc_options *opts)
{ {
tree t; tree t;
void **slot;
/* Use the cache of optimization nodes. */ /* Use the cache of optimization nodes. */
cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node), cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node),
opts); opts);
slot = htab_find_slot (cl_option_hash_table, cl_target_option_node, INSERT); tree *slot = cl_option_hash_table->find_slot (cl_target_option_node, INSERT);
t = (tree) *slot; t = *slot;
if (!t) if (!t)
{ {
/* Insert this one into the hash table. */ /* Insert this one into the hash table. */
...@@ -11619,26 +11619,16 @@ build_target_option_node (struct gcc_options *opts) ...@@ -11619,26 +11619,16 @@ build_target_option_node (struct gcc_options *opts)
return t; 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, /* Clear TREE_TARGET_GLOBALS of all TARGET_OPTION_NODE trees,
so that they aren't saved during PCH writing. */ so that they aren't saved during PCH writing. */
void void
prepare_target_option_nodes_for_pch (void) prepare_target_option_nodes_for_pch (void)
{ {
htab_traverse (cl_option_hash_table, prepare_target_option_node_for_pch, hash_table<cl_option_hasher>::iterator iter = cl_option_hash_table->begin ();
NULL); 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 /* Determine the "ultimate origin" of a block. The block may be an inlined
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment