Author: leo
Date: Mon Nov 7 05:48:24 2005
New Revision: 9816
Modified:
trunk/ast/node.c
trunk/imcc/cfg.c
trunk/imcc/debug.c
trunk/imcc/imc.c
trunk/imcc/imc.h
trunk/imcc/pbc.c
trunk/imcc/pcc.c
trunk/imcc/reg_alloc.c
trunk/imcc/symreg.c
trunk/imcc/symreg.h
trunk/imcc/unit.h
Log:
Speed up PASM/PIR compilation by several magnitudes
* the SymReg hash was fixed sized with ~25K entries
* imcc had spent by far most of it's time during just walking the
hash data buffer
* this is now improved by using variable sized hash data storage
---
* fixed bug #37627 reported by Nick Glencross
Modified: trunk/ast/node.c
==============================================================================
--- trunk/ast/node.c (original)
+++ trunk/ast/node.c Mon Nov 7 05:48:24 2005
@@ -1067,7 +1067,7 @@ create_Func(int nr, nodeType *self, node
self = create_1(nr, self, child);
r = child->u.r;
last = cur_unit->prev; /* XXX ->caller */
- r = _get_sym(last->hash, r->name);
+ r = _get_sym(&last->hash, r->name);
if (r) {
/* mark the name being a subroutine name
* s. Py_Local
Modified: trunk/imcc/cfg.c
==============================================================================
--- trunk/imcc/cfg.c (original)
+++ trunk/imcc/cfg.c Mon Nov 7 05:48:24 2005
@@ -61,14 +61,15 @@ find_basic_blocks (Parrot_Interp interpr
{
Basic_block *bb;
Instruction *ins;
+ SymHash *hsh = &unit->hash;
+ SymReg * r;
int nu = 0;
int i;
IMCC_info(interpreter, 2, "find_basic_blocks\n");
init_basic_blocks(unit);
- for (i = 0; i < HASH_SIZE; i++) {
- SymReg * r;
- for (r = unit->hash[i]; r; r = r->next) {
+ for (i = 0; i < hsh->size; i++) {
+ for (r = hsh->data[i]; r; r = r->next) {
if (r && (r->type & VTADDRESS)) {
r->last_ins = NULL;
}
@@ -140,7 +141,7 @@ find_basic_blocks (Parrot_Interp interpr
*/
if (!strcmp(ins->op, "bsr") || !strcmp(ins->op, "set_addr")) {
char *name = ins->r[0]->name;
- SymReg *r = get_sym(name);
+ r = get_sym(name);
if (*ins->op == 'b') { /* bsr */
Instruction * lab;
found = r != NULL && r->first_ins;
Modified: trunk/imcc/debug.c
==============================================================================
--- trunk/imcc/debug.c (original)
+++ trunk/imcc/debug.c Mon Nov 7 05:48:24 2005
@@ -158,17 +158,20 @@ void
dump_labels(IMC_Unit * unit)
{
int i;
+ SymHash *hsh = &unit->hash;
+ SymReg * r;
fprintf(stderr, "Labels\n");
fprintf(stderr, "name\tpos\tlast ref\n"
"-----------------------\n");
- for(i = 0; i < HASH_SIZE; i++) {
- SymReg * r = unit->hash[i];
+ for (i = 0; i < hsh->size; i++) {
+ for (r = hsh->data[i]; r; r = r->next) {
if (r && (r->type & VTADDRESS))
fprintf(stderr, "%s\t%d\t%d\n",
r->name,
r->first_ins ? r->first_ins->index : -1,
r->last_ins ? r->last_ins->index : -1);
+ }
}
fprintf(stderr, "\n");
}
Modified: trunk/imcc/imc.c
==============================================================================
--- trunk/imcc/imc.c (original)
+++ trunk/imcc/imc.c Mon Nov 7 05:48:24 2005
@@ -82,8 +82,8 @@ void
imc_cleanup(Interp *interp)
{
clear_globals(interp);
- mem_sys_free(IMCC_INFO(interp)->ghash);
- IMCC_INFO(interp)->ghash = NULL;
+ mem_sys_free(IMCC_INFO(interp)->ghash.data);
+ IMCC_INFO(interp)->ghash.data = NULL;
}
@@ -94,7 +94,7 @@ static IMC_Unit *
imc_new_unit(IMC_Unit_Type t)
{
IMC_Unit * unit = calloc(1, sizeof(IMC_Unit));
- unit->hash = mem_sys_allocate_zeroed(HASH_SIZE * sizeof(SymReg*));
+ create_symhash(&unit->hash);
unit->type = t;
return unit;
}
@@ -114,8 +114,8 @@ imc_open_unit(Parrot_Interp interp, IMC_
imc_info = IMCC_INFO(interp);
if (!imc_info->imc_units)
imc_info->imc_units = unit;
- if (!imc_info->ghash)
- imc_info->ghash = mem_sys_allocate_zeroed(HASH_SIZE * sizeof(SymReg*));
+ if (!imc_info->ghash.data)
+ create_symhash(&imc_info->ghash);
unit->prev = imc_info->last_unit;
if (imc_info->last_unit)
imc_info->last_unit->next = unit;
@@ -161,7 +161,7 @@ imc_free_unit(Parrot_Interp interp, IMC_
imc->n_comp_units--;
clear_locals(unit);
- free(unit->hash);
+ free(unit->hash.data);
free(unit);
}
Modified: trunk/imcc/imc.h
==============================================================================
--- trunk/imcc/imc.h (original)
+++ trunk/imcc/imc.h Mon Nov 7 05:48:24 2005
@@ -197,7 +197,7 @@ typedef struct _imc_info_t {
int dont_optimize;
int has_compile;
int allocated;
- SymReg ** ghash;
+ SymHash ghash;
SymReg * cur_namespace;
struct nodeType_t *top_node;
Modified: trunk/imcc/pbc.c
==============================================================================
--- trunk/imcc/pbc.c (original)
+++ trunk/imcc/pbc.c Mon Nov 7 05:48:24 2005
@@ -42,8 +42,8 @@ struct subs {
size_t size; /* code size in ops */
int ins_line; /* line# for debug */
int n_basic_blocks; /* block count */
- SymReg * labels[HASH_SIZE]; /* label names */
- SymReg * bsrs[HASH_SIZE]; /* bsr, set_addr locations */
+ SymHash labels; /* label names */
+ SymHash bsrs; /* bsr, set_addr locations */
IMC_Unit * unit;
int pmc_const; /* index in const table */
struct subs *prev;
@@ -58,7 +58,7 @@ struct cs_t {
struct subs *first; /* first sub of code segment */
struct cs_t *prev; /* previous code segment */
struct cs_t *next; /* next code segment */
- SymReg * key_consts[HASH_SIZE]; /* cached key constants for this seg */
+ SymHash key_consts; /* cached key constants for this seg */
int pic_idx; /* next index of PIC */
};
@@ -88,8 +88,8 @@ imcc_globals_destroy(int ex, void *param
s = cs->subs;
while (s) {
prev_s = s->prev;
- clear_sym_hash(s->labels);
- clear_sym_hash(s->bsrs);
+ clear_sym_hash(&s->labels);
+ clear_sym_hash(&s->bsrs);
mem_sys_free(s);
s = prev_s;
}
@@ -117,9 +117,10 @@ e_pbc_open(Interp * interpreter, void *p
cs->prev = globals.cs;
/* free previous cached key constants if any */
if (globals.cs) {
- SymReg **h = globals.cs->key_consts;
+ SymHash *h = &globals.cs->key_consts;
clear_sym_hash(h);
}
+ create_symhash(&cs->key_consts);
cs->next = NULL;
cs->subs = NULL;
cs->first = NULL;
@@ -206,6 +207,8 @@ make_new_sub(Interp *interpreter, IMC_Un
if (!globals.cs->first)
globals.cs->first = s;
globals.cs->subs = s;
+ create_symhash(&s->labels);
+ create_symhash(&s->bsrs);
#ifdef HAS_JIT
if ((IMCC_INFO(interpreter)->optimizer_level & OPT_J)) {
allocate_jit(interpreter, unit);
@@ -245,8 +248,8 @@ static void
store_label(Interp *interpreter, SymReg * r, int pc)
{
SymReg * label;
- label = _mk_address(interpreter, globals.cs->subs->labels,
str_dup(r->name),
- U_add_uniq_label);
+ label = _mk_address(interpreter, &globals.cs->subs->labels,
+ str_dup(r->name), U_add_uniq_label);
label->color = pc;
}
@@ -254,7 +257,8 @@ static void
store_bsr(Interp *interpreter, SymReg * r, int pc, int offset)
{
SymReg * bsr;
- bsr = _mk_address(interpreter, globals.cs->subs->bsrs, str_dup(r->name),
U_add_all);
+ bsr = _mk_address(interpreter, &globals.cs->subs->bsrs,
+ str_dup(r->name), U_add_all);
if (r->set == 'p')
bsr->set = 'p';
bsr->color = pc;
@@ -270,7 +274,7 @@ static void
store_key_const(char * str, int idx)
{
SymReg * c;
- c = _mk_const(globals.cs->key_consts, str_dup(str), 0);
+ c = _mk_const(&globals.cs->key_consts, str_dup(str), 0);
c->color = idx;
}
@@ -383,7 +387,7 @@ store_labels(Interp *interpreter, IMC_Un
if (addr->type & VTREGISTER)
continue;
/* branch found */
- label = _get_sym(globals.cs->subs->labels, addr->name);
+ label = _get_sym(&globals.cs->subs->labels, addr->name);
/* maybe global */
if (label)
continue;
@@ -442,7 +446,7 @@ find_global_label(char *name, struct sub
|| (sym->unit->namespace && !s->unit->namespace)
|| (!sym->unit->namespace && s->unit->namespace)))
continue;
- if ( (r = _get_sym(s->labels, name)) ) {
+ if ( (r = _get_sym(&s->labels, name)) ) {
*pc += r->color; /* here pc was stored */
*s1 = s;
return r;
@@ -461,10 +465,12 @@ fixup_bsrs(Interp *interpreter)
struct subs *s, *s1;
int jumppc = 0;
int pmc_const;
+ SymHash *hsh;
for (s = globals.cs->first; s; s = s->next) {
- for (i = 0; i < HASH_SIZE; i++) {
- for (bsr = s->bsrs[i]; bsr; bsr = bsr->next ) {
+ hsh = &s->bsrs;
+ for (i = 0; i < hsh->size; i++) {
+ for (bsr = hsh->data[i]; bsr; bsr = bsr->next ) {
#if IMC_TRACE_HIGH
fprintf(stderr, "fixup_bsr %s\n", bsr->name);
#endif
@@ -752,7 +758,7 @@ add_const_key(Interp *interpreter, opcod
struct PackFile_Constant *pfc;
opcode_t *rc;
- if ( (r = _get_sym(globals.cs->key_consts, s_key)) != 0)
+ if ( (r = _get_sym(&globals.cs->key_consts, s_key)) != 0)
return r->color;
pfc = malloc(sizeof(struct PackFile_Constant));
rc = PackFile_Constant_unpack_key(interpreter,
@@ -981,19 +987,25 @@ constant_folding(Interp *interpreter, IM
{
SymReg * r;
int i;
+ SymHash *hsh;
/* go through all consts of current sub */
- for (i = 0; i < HASH_SIZE; i++) {
+ hsh = &IMCC_INFO(interpreter)->ghash;
+ for (i = 0; i < hsh->size; i++) {
/* normally constants are in ghash ... */
- for (r = IMCC_INFO(interpreter)->ghash[i]; r; r = r->next) {
+ for (r = hsh->data[i]; r; r = r->next) {
if (r->type & (VTCONST|VT_CONSTP)) {
add_1_const(interpreter, r);
}
}
- /* ... but keychains 'K' are in local hash, they may contain
- * variables and constants
- */
- for (r = unit->hash[i]; r; r = r->next) {
+ }
+ /* ... but keychains 'K' are in local hash, they may contain
+ * variables and constants
+ */
+ hsh = &unit->hash;
+ for (i = 0; i < hsh->size; i++) {
+ /* normally constants are in ghash ... */
+ for (r = hsh->data[i]; r; r = r->next) {
if (r->type & VTCONST) {
add_1_const(interpreter, r);
}
@@ -1190,7 +1202,7 @@ e_pbc_emit(Interp *interpreter, void *pa
PIO_eprintf(NULL, "emit_pbc: op [%d %s]\n", ins->opnum, ins->op);
#endif
if ((addr = get_branch_reg(ins)) != 0 && !(addr->type & VTREGISTER)) {
- SymReg *label = _get_sym(globals.cs->subs->labels, addr->name);
+ SymReg *label = _get_sym(&globals.cs->subs->labels, addr->name);
/* maybe global */
if (label) {
addr->color = label->color - npc;
Modified: trunk/imcc/pcc.c
==============================================================================
--- trunk/imcc/pcc.c (original)
+++ trunk/imcc/pcc.c Mon Nov 7 05:48:24 2005
@@ -48,7 +48,7 @@ get_pasm_reg(Interp* interp, char *name)
{
SymReg *r;
- if ((r = _get_sym(cur_unit->hash, name)))
+ if ((r = _get_sym(&cur_unit->hash, name)))
return r;
return mk_pasm_reg(interp, str_dup(name));
}
@@ -61,7 +61,7 @@ get_const(Interp *interp, const char *na
{
SymReg *r;
- if ((r = _get_sym(IMCC_INFO(interp)->ghash, name)) && r->set == type)
+ if ((r = _get_sym(&IMCC_INFO(interp)->ghash, name)) && r->set == type)
return r;
return mk_const(interp, str_dup(name), type);
}
Modified: trunk/imcc/reg_alloc.c
==============================================================================
--- trunk/imcc/reg_alloc.c (original)
+++ trunk/imcc/reg_alloc.c Mon Nov 7 05:48:24 2005
@@ -196,9 +196,13 @@ make_stat(IMC_Unit * unit, int *sets, in
/* register usage summary */
char type[] = "INSP";
int i, j;
- for (i = 0; i < HASH_SIZE; i++) {
- SymReg * r = unit->hash[i];
- for (; r; r = r->next)
+ SymHash *hsh = &unit->hash;
+ SymReg * r;
+
+ for (i = 0; i < hsh->size; i++) {
+ for (r = hsh->data[i]; r; r = r->next) {
+ if (r->color > unit->max_color)
+ unit->max_color = r->color;
for (j = 0; j < 4; j++)
if (r->set == type[j] && (r->type & VTREGISTER)) {
if (sets)
@@ -207,6 +211,7 @@ make_stat(IMC_Unit * unit, int *sets, in
if (r->color > cols[j])
cols[j] = r->color;
}
+ }
}
if (cols) {
for (j = 0; j < 4; j++)
@@ -307,30 +312,22 @@ static void
build_reglist(Parrot_Interp interpreter, IMC_Unit * unit, int first)
{
int i, count, unused, n_symbols;
+ SymHash *hsh = &unit->hash;
+ SymReg * r;
UNUSED(first);
IMCC_info(interpreter, 2, "build_reglist\n");
/* count symbols */
if (unit->reglist)
free_reglist(unit);
- for (i = count = 0; i < HASH_SIZE; i++) {
- SymReg * r = unit->hash[i];
- for (; r; r = r->next) {
- if (r->type & VTREGISTER)
- count++;
- }
- }
+ count = unit->hash.entries;
if (count == 0)
return;
- if (count >= HASH_SIZE)
- IMCC_warning(interpreter, "build_reglist: probably too small HASH_SIZE"
- " (%d symbols)\n", count);
unit->reglist = mem_sys_allocate(count * sizeof(SymReg*));
- for (i = count = 0; i < HASH_SIZE; i++) {
- SymReg * r = unit->hash[i];
- /* Add each symbol to reglist */
- for (; r; r = r->next) {
+ for (i = count = 0; i < hsh->size; i++) {
+ for (r = hsh->data[i]; r; r = r->next) {
+ /* Add each symbol to reglist */
if (r->type & VTREGISTER) {
unit->reglist[count++] = r;
}
@@ -739,14 +736,17 @@ try_allocate(Parrot_Interp interpreter,
int x = 0;
int color;
char *avail;
- int t;
+ int t, n;
unsigned int *graph = unit->interference_graph;
SymReg ** reglist = unit->reglist;
/*
* unit->n_symbols should be an upper limit of needed colors
*/
- avail = mem_sys_allocate(unit->n_symbols + 1);
+ n = unit->n_symbols;
+ if (unit->max_color > n)
+ n = unit->max_color;
+ avail = mem_sys_allocate(n + 1);
while ((imcstack_depth(nodeStack) > 0) ) {
x=imcstack_pop(nodeStack);
Modified: trunk/imcc/symreg.c
==============================================================================
--- trunk/imcc/symreg.c (original)
+++ trunk/imcc/symreg.c Mon Nov 7 05:48:24 2005
@@ -52,11 +52,11 @@ pop_namespace(char * name)
/* Gets a symbol from the hash */
static SymReg *
-_get_sym_typed(SymReg * hsh[], const char * name, int t)
+_get_sym_typed(SymHash * hsh, const char * name, int t)
{
SymReg * p;
- int i = hash_str(name) % HASH_SIZE;
- for (p = hsh[i]; p; p = p->next) {
+ int i = hash_str(name) % hsh->size;
+ for (p = hsh->data[i]; p; p = p->next) {
if (!strcmp(name, p->name) && t == p->set)
return p;
}
@@ -73,7 +73,7 @@ _get_sym_typed(SymReg * hsh[], const cha
* should be changed.
*/
SymReg *
-_mk_symreg(SymReg* hsh[], char * name, int t)
+_mk_symreg(SymHash* hsh, char * name, int t)
{
SymReg * r;
if ((r = _get_sym_typed(hsh, name, t))) {
@@ -100,7 +100,7 @@ SymReg *
mk_symreg(Interp *interp, char * name, int t)
{
IMC_Unit *unit = IMCC_INFO(interp)->last_unit;
- return _mk_symreg(unit->hash, name, t);
+ return _mk_symreg(&unit->hash, name, t);
}
/*
@@ -140,7 +140,7 @@ mk_temp_reg(Interp *interp, int t)
SymReg *
mk_pcc_sub(Interp *interp, char * name, int proto) {
IMC_Unit *unit = IMCC_INFO(interp)->last_unit;
- SymReg *r = _mk_symreg(unit->hash, name, proto);
+ SymReg *r = _mk_symreg(&unit->hash, name, proto);
r->type = VT_PCC_SUB;
r->pcc_sub = calloc(1, sizeof(struct pcc_sub_t));
return r;
@@ -166,9 +166,9 @@ add_namespace(Parrot_Interp interp, IMC_
unit->namespace = g;
g->reg = ns;
g->type = VT_CONSTP;
- if (! (r = _get_sym(IMCC_INFO(interp)->ghash, g->name)) ||
+ if (! (r = _get_sym(&IMCC_INFO(interp)->ghash, g->name)) ||
r->type != VT_CONSTP )
- _store_symreg(IMCC_INFO(interp)->ghash, g);
+ _store_symreg(&IMCC_INFO(interp)->ghash, g);
}
}
@@ -239,7 +239,7 @@ SymReg *
mk_pasm_reg(Interp *interp, char * name)
{
SymReg * r;
- if ((r = _get_sym(cur_unit->hash, name))) {
+ if ((r = _get_sym(&cur_unit->hash, name))) {
free(name);
return r;
}
@@ -352,7 +352,7 @@ mk_const_ident(Interp *interp,
IMCC_fataly(interp, E_SyntaxError,
"global PMC constant not allowed");
}
- r = _mk_symreg(IMCC_INFO(interp)->ghash, name, t);
+ r = _mk_symreg(&IMCC_INFO(interp)->ghash, name, t);
}
else {
if (t == 'P') {
@@ -368,7 +368,7 @@ mk_const_ident(Interp *interp,
/* Makes a new constant*/
SymReg *
-_mk_const(SymReg *hsh[], char * name, int t)
+_mk_const(SymHash *hsh, char * name, int t)
{
SymReg * r = _mk_symreg(hsh, name, t);
r->type = VTCONST;
@@ -384,10 +384,9 @@ _mk_const(SymReg *hsh[], char * name, in
SymReg *
mk_const(Interp *interp, char * name, int t)
{
- SymReg **h = IMCC_INFO(interp)->ghash;
- if (!h)
- h = IMCC_INFO(interp)->ghash =
- mem_sys_allocate_zeroed(HASH_SIZE * sizeof(SymReg*));
+ SymHash *h = &IMCC_INFO(interp)->ghash;
+ if (!h->data)
+ create_symhash(h);
return _mk_const(h, name, t);
}
@@ -425,7 +424,7 @@ add_ns(char *name)
/* Makes a new address */
SymReg *
-_mk_address(Interp *interp, SymReg *hsh[], char * name, int uniq)
+_mk_address(Interp *interp, SymHash *hsh, char * name, int uniq)
{
SymReg * r;
if (uniq == U_add_all) {
@@ -462,7 +461,7 @@ SymReg *
mk_address(Interp *interp, char * name, int uniq)
{
SymReg * s;
- SymReg ** h = *name == '_' ? IMCC_INFO(interp)->ghash : cur_unit->hash;
+ SymHash *h = *name == '_' ? &IMCC_INFO(interp)->ghash : &cur_unit->hash;
s = _mk_address(interp, h, name, uniq);
if (*name == '_')
s->usage |= U_FIXUP;
@@ -476,7 +475,7 @@ mk_address(Interp *interp, char * name,
SymReg *
mk_sub_label(Interp *interp, char * name)
{
- SymReg * s = _mk_address(interp, IMCC_INFO(interp)->ghash,
+ SymReg * s = _mk_address(interp, &IMCC_INFO(interp)->ghash,
name, U_add_uniq_sub);
s->usage |= U_FIXUP;
return s;
@@ -488,7 +487,7 @@ mk_sub_label(Interp *interp, char * name
SymReg *
mk_sub_address(Interp *interp, char * name)
{
- SymReg * s = _mk_address(interp, IMCC_INFO(interp)->ghash,
+ SymReg * s = _mk_address(interp, &IMCC_INFO(interp)->ghash,
name, U_add_all);
s->usage |= U_FIXUP;
return s;
@@ -501,7 +500,7 @@ SymReg *
mk_local_label(Interp *interp, char * name)
{
IMC_Unit *unit = IMCC_INFO(interp)->last_unit;
- return _mk_address(interp, unit->hash, name, U_add_uniq_label);
+ return _mk_address(interp, &unit->hash, name, U_add_uniq_label);
}
/*
@@ -511,7 +510,7 @@ SymReg *
mk_label_address(Interp *interp, char * name)
{
IMC_Unit *unit = IMCC_INFO(interp)->last_unit;
- return _mk_address(interp, unit->hash, name, U_add_once);
+ return _mk_address(interp, &unit->hash, name, U_add_once);
}
@@ -569,7 +568,7 @@ link_keys(Interp *interp, int nargs, Sym
int i, len, any_slice;
char *key_str;
/* namespace keys are global consts - no cur_unit */
- SymReg **h = cur_unit ? cur_unit->hash : IMCC_INFO(interp)->ghash;
+ SymHash *h = cur_unit ? &cur_unit->hash : &IMCC_INFO(interp)->ghash;
if (nargs == 0)
IMCC_fataly(interp, E_SyntaxError,
@@ -653,31 +652,83 @@ free_sym(SymReg *r)
*
*/
+void
+create_symhash(SymHash *hash)
+{
+ hash->data = mem_sys_allocate_zeroed(16 * sizeof(SymReg*));
+ hash->size = 16;
+ hash->entries = 0;
+}
+
+static void
+resize_symhash(SymHash *hsh)
+{
+ SymHash nh;
+ SymReg *r, *next;
+ int new_size = hsh->size << 1;
+ int i, new_i;
+ SymReg ** next_r;
+ int n_next, j, k;
+
+ nh.data = mem_sys_allocate_zeroed(new_size * sizeof(SymReg*));
+ n_next = 16;
+ next_r = mem_sys_allocate_zeroed(n_next * sizeof(SymReg*));
+ for (i = 0; i < hsh->size; i++) {
+ j = 0;
+ for (r = hsh->data[i]; r; r = next) {
+ next = r->next;
+ /*
+ * have to remember all the chained next pointers and
+ * clear r->next
+ */
+ if (j >= n_next) {
+ n_next <<= 1;
+ next_r = mem_sys_realloc(next_r, n_next * sizeof(SymReg*));
+ }
+ r->next = NULL;
+ next_r[j++] = r;
+ }
+ for (k = 0; k < j; ++k) {
+ r = next_r[k];
+ new_i = hash_str(r->name) % new_size;
+ r->next = nh.data[new_i];
+ nh.data[new_i] = r;
+ }
+ }
+ mem_sys_free(hsh->data);
+ mem_sys_free(next_r);
+ hsh->data = nh.data;
+ hsh->size = new_size;
+}
+
/* Stores a symbol into the hash */
void
-_store_symreg(SymReg *hsh[], SymReg * r)
+_store_symreg(SymHash *hsh, SymReg * r)
{
- int i = hash_str(r->name) % HASH_SIZE;
+ int i = hash_str(r->name) % hsh->size;
#if IMC_TRACE_HIGH
printf(" store [%s]\n", r->name);
#endif
- r->next = hsh[i];
- hsh[i] = r;
+ r->next = hsh->data[i];
+ hsh->data[i] = r;
+ hsh->entries++;
+ if (hsh->entries >= hsh->size)
+ resize_symhash(hsh);
}
void
store_symreg(SymReg * r)
{
- _store_symreg(cur_unit->hash, r);
+ _store_symreg(&cur_unit->hash, r);
}
/* Gets a symbol from the hash */
SymReg *
-_get_sym(SymReg * hsh[], const char * name)
+_get_sym(SymHash * hsh, const char * name)
{
SymReg * p;
- int i = hash_str(name) % HASH_SIZE;
- for (p = hsh[i]; p; p = p->next) {
+ int i = hash_str(name) % hsh->size;
+ for (p = hsh->data[i]; p; p = p->next) {
#if IMC_TRACE_HIGH
printf(" [%s]\n", p->name);
#endif
@@ -691,12 +742,12 @@ _get_sym(SymReg * hsh[], const char * na
SymReg *
get_sym(const char * name)
{
- return _get_sym(cur_unit->hash, name);
+ return _get_sym(&cur_unit->hash, name);
}
/* find a symbol hash or ghash */
SymReg *
-_find_sym(Interp *interp, Namespace * nspace, SymReg * hsh[],
+_find_sym(Interp *interp, Namespace * nspace, SymHash * hsh,
const char * name)
{
Namespace * ns;
@@ -712,7 +763,7 @@ _find_sym(Interp *interp, Namespace * ns
p = _get_sym(hsh, name);
if (p)
return p;
- p = _get_sym(IMCC_INFO(interp)->ghash, name);
+ p = _get_sym(&IMCC_INFO(interp)->ghash, name);
if (p)
return p;
return 0;
@@ -723,57 +774,34 @@ SymReg *
find_sym(Interp *interp, const char * name)
{
if (cur_unit)
- return _find_sym(interp, namespace, cur_unit->hash, name);
+ return _find_sym(interp, namespace, &cur_unit->hash, name);
return NULL;
}
void
-_delete_sym(Interp* interp, IMC_Unit * unit, const char * name)
-{
- SymReg ** p;
- int i = hash_str(name) % HASH_SIZE;
- for (p = &unit->hash[i]; *p; p = &(*p)->next) {
- SymReg * deadmeat = *p;
- if (!strcmp(name, deadmeat->name)) {
- *p = deadmeat->next;
- if (deadmeat->life_info){
- free_life_info(unit, deadmeat);
- }
- free_sym(deadmeat);
- return;
- }
- }
-
- IMCC_fatal(interp, 1,
- "_delete_sym: tried to delete nonexistent symbol '%s'\n", name);
-}
-
-
-void
-clear_sym_hash(SymReg **hsh)
+clear_sym_hash(SymHash *hsh)
{
int i;
SymReg * p, *next;
- for (i = 0; i < HASH_SIZE; i++) {
- for (p = hsh[i]; p; ) {
+ for (i = 0; i < hsh->size; i++) {
+ for (p = hsh->data[i]; p; ) {
next = p->next;
- free_sym(p);
- p = next;
- }
- hsh[i] = NULL;
+ free_sym(p);
+ p = next;
+ }
+ hsh->data[i] = NULL;
}
+ hsh->entries = 0;
}
-void debug_dump_sym_hash(SymReg **hsh);
-
void
-debug_dump_sym_hash(SymReg **hsh)
+debug_dump_sym_hash(SymHash *hsh)
{
int i;
SymReg * p;
- for (i = 0; i < HASH_SIZE; i++) {
- for (p = hsh[i]; p; p = p->next) {
+ for (i = 0; i < hsh->size; i++) {
+ for (p = hsh->data[i]; p; p = p->next) {
fprintf(stderr, "%s ", p->name);
}
}
@@ -785,9 +813,9 @@ clear_locals(IMC_Unit * unit)
{
int i;
SymReg * p, *next;
- SymReg **hsh = unit->hash;
- for (i = 0; i < HASH_SIZE; i++) {
- for (p = hsh[i]; p; ) {
+ SymHash *hsh = &unit->hash;
+ for (i = 0; i < hsh->size; i++) {
+ for (p = hsh->data[i]; p; ) {
next = p->next;
if (unit && p->life_info) {
free_life_info(unit, p);
@@ -795,29 +823,20 @@ clear_locals(IMC_Unit * unit)
free_sym(p);
p = next;
}
- hsh[i] = NULL;
+ hsh->data[i] = NULL;
}
+ hsh->entries = 0;
}
/* Clear global symbols */
void
clear_globals(Interp *interp)
{
- int i;
- SymReg * p, *next;
+ SymHash *hsh = &IMCC_INFO(interp)->ghash;
- if (!IMCC_INFO(interp)->ghash)
+ if (!hsh->data)
return;
- for (i = 0; i < HASH_SIZE; i++) {
- for (p = IMCC_INFO(interp)->ghash[i]; p; ) {
- next = p->next;
- if (p->type & VTADDRESS)
- p->first_ins = p->last_ins = NULL;
- free_sym(p);
- p = next;
- }
- IMCC_INFO(interp)->ghash[i] = NULL;
- }
+ clear_sym_hash(hsh);
}
Modified: trunk/imcc/symreg.h
==============================================================================
--- trunk/imcc/symreg.h (original)
+++ trunk/imcc/symreg.h Mon Nov 7 05:48:24 2005
@@ -1,11 +1,6 @@
#if !defined(PARROT_IMCC_SYMREG_H_GUARD)
#define PARROT_IMCC_SYMREG_H_GUARD
-/* constants */
-
-#define HASH_SIZE 25013
-
-
/* types */
enum VARTYPE { /* variable type can be */
@@ -84,6 +79,11 @@ typedef struct _SymReg {
int pmc_type; /* class enum */
} SymReg;
+typedef struct _SymHash {
+ SymReg ** data;
+ int size;
+ int entries;
+} SymHash;
/* namespaces */
@@ -184,20 +184,22 @@ SymReg * find_sym(Interp *, const char *
SymReg * get_sym(const char * name);
SymReg* get_pasm_reg(Interp* interpreter, char *name);
SymReg* get_const(Interp *interpreter, const char *name, int type);
-SymReg * _get_sym(SymReg * hash[], const char * name);
-SymReg * _mk_symreg(SymReg* hash[],char * name, int t);
-SymReg * _mk_const(SymReg *hash[], char * name, int t);
-void _store_symreg(SymReg *hash[], SymReg * r);
-SymReg * _mk_address(Interp *, SymReg *hash[], char * name, int uniq);
+SymReg * _get_sym(SymHash *hash, const char * name);
+SymReg * _mk_symreg(SymHash *hash,char * name, int t);
+void create_symhash(SymHash *hash);
+SymReg * _mk_const(SymHash *hash, char * name, int t);
+void _store_symreg(SymHash *hash, SymReg * r);
+SymReg * _mk_address(Interp *, SymHash *hash, char * name, int uniq);
SymReg * link_keys(Interp *, int nargs, SymReg *keys[]);
void clear_locals(struct _IMC_Unit *);
-void clear_sym_hash(SymReg **);
+void clear_sym_hash(SymHash *);
void clear_globals(Interp *);
unsigned int hash_str(const char * str);
-void _delete_sym(Interp *, struct _IMC_Unit *, const char * name);
SymReg * dup_sym(SymReg *r);
+void debug_dump_sym_hash(SymHash *hsh);
-SymReg * _find_sym(Interp *,Namespace * ns, SymReg * hash[], const char *
name);
+
+SymReg * _find_sym(Interp *,Namespace * ns, SymHash *hash, const char * name);
char * _mk_fullname(Namespace * ns, const char * name);
char * mk_fullname(const char * name);
void push_namespace(char * name);
@@ -206,3 +208,13 @@ void pop_namespace(char * name);
#endif /* PARROT_IMCC_SYMREG_H_GUARD */
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+*/
+
Modified: trunk/imcc/unit.h
==============================================================================
--- trunk/imcc/unit.h (original)
+++ trunk/imcc/unit.h Mon Nov 7 05:48:24 2005
@@ -20,7 +20,7 @@ typedef struct _IMC_Unit {
IMC_Unit_Type type;
Instruction * instructions;
Instruction * last_ins;
- SymReg ** hash;
+ SymHash hash;
Symbol * sym;
int bb_list_size;
int n_basic_blocks;
@@ -36,6 +36,7 @@ typedef struct _IMC_Unit {
unsigned int* interference_graph;
SymReg** reglist;
int n_symbols;
+ int max_color;
struct _IMC_Unit * prev;
struct _IMC_Unit * next;