scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 12d82a8fefc00b701aa55f957a2a8da22e72885a
parent 543ec38258d6de262c01d186939d3836d401099e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 28 Jul 2012 23:34:10 +0200

Removed global variable yyhash

This global variable was used for improve the speed of the hash search,
doing the hash key calculation while the string is read from the input, but
this cause that all the modules has to know about the hash. This is a very
clear example of prior optimzation.

Diffstat:
Mdecl.c | 8++++----
Mkeyword.c | 2+-
Mlex.c | 11++++-------
Msymbol.c | 27+++++++++++++--------------
Msymbol.h | 5++---
Mtokens.h | 1-
6 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/decl.c b/decl.c @@ -13,12 +13,12 @@ char parser_out_home; static void declarator(void); -static struct symbol *newiden(char *s, unsigned char key) +static struct symbol *newiden(char *s) { - register struct symbol *sym = lookup(yytext, yyhash); + register struct symbol *sym = lookup(yytext); if (!sym) - sym = install(yytext, yyhash); + sym = install(yytext); else if (sym->level == nested_level) error("redeclaration of '%s'", yytext); return sym; @@ -30,7 +30,7 @@ static void dirdcl(void) declarator(); expect(')'); } else if (yytoken == IDEN) { - newiden(yytext, yyhash); + newiden(yytext); next(); } else { error("expected '(' or identifier before of '%s'", yytext); diff --git a/keyword.c b/keyword.c @@ -52,7 +52,7 @@ void init_keywords(void) init_symbol(); for (bp = keywords; bp->str; bp++) { - sym = install(bp->str, hashfun(bp->str)); + sym = install(bp->str); sym->tok = bp->tok; sym->ns = NS_KEYWORD; } diff --git a/lex.c b/lex.c @@ -13,7 +13,6 @@ static FILE *yyin; union yyval yyval; static unsigned char aheadtok = NOTOK; unsigned char yytoken; -unsigned char yyhash; char yytext[TOKSIZ_MAX + 1]; unsigned linenum; unsigned columnum; @@ -34,7 +33,7 @@ static char number(void) error("identifier too long %s", yytext); *bp = '\0'; ungetc(ch, yyin); - yyval.sym = sym = install(NULL, 0); + yyval.sym = sym = install(NULL); sym->val = atoi(yytext); return CONSTANT; @@ -42,20 +41,18 @@ static char number(void) static unsigned char iden(void) { - register char ch; - register char *bp = yytext; + register char ch, *bp; register struct symbol *sym; - for (yyhash = 0; bp < yytext + TOKSIZ_MAX; *bp++ = ch) { + for (bp = yytext; bp < yytext + TOKSIZ_MAX; *bp++ = ch) { if (!isalnum(ch = getc(yyin)) && ch != '_') break; - yyhash += ch; } if (bp == yytext + TOKSIZ_MAX) error("identifier too long %s", yytext); *bp = '\0'; ungetc(ch, yyin); - if ((sym = lookup(yytext, yyhash)) && sym->ns == NS_KEYWORD) + if ((sym = lookup(yytext)) && sym->ns == NS_KEYWORD) return sym->tok; yyval.sym = sym; return IDEN; diff --git a/symbol.c b/symbol.c @@ -45,20 +45,28 @@ void del_ctx(void) del_hash_ctx(&iden_hash, ctx_head->next->iden); } -struct symbol *install(const char *s, unsigned char key) +static inline unsigned char hashfun(register const char *s) +{ + register unsigned char h, ch; + + for (h = 0; ch = *s++; h += ch) + /* nothing */; + return h & NR_SYM_HASH - 1; +} + +struct symbol *install(const char *s) { static struct symbol *head; register struct symbol *sym, *next; sym = xmalloc(sizeof(*sym)); - sym->next = iden_hash.top; iden_hash.top = sym; if (s) { sym->str = xstrdup(s); sym->ns = NS_IDEN; - head = &iden_hash.buf[key & NR_SYM_HASH-1]; + head = &iden_hash.buf[hashfun(s)]; next = head->h_next; sym->h_next = next; sym->h_prev = next->h_prev; @@ -71,11 +79,11 @@ struct symbol *install(const char *s, unsigned char key) return sym; } -struct symbol *lookup(char *s, unsigned char key) +struct symbol *lookup(char *s) { register struct symbol *bp, *head; - head = &iden_hash.buf[key & NR_SYM_HASH-1]; + head = &iden_hash.buf[hashfun(s)]; for (bp = head->h_next; bp != head; bp = bp->h_next) { if (!strcmp(bp->str, s)) return bp; @@ -90,12 +98,3 @@ void init_symbol(void) for (bp = iden_hash.buf; bp < &iden_hash.buf[NR_SYM_HASH]; ++bp) bp->h_next = bp->h_prev = bp; } - -unsigned char hashfun(register const char *s) -{ - register unsigned char h, ch; - - for (h = 0; ch = *s++; h += ch) - /* nothing */; - return h; -} diff --git a/symbol.h b/symbol.h @@ -61,9 +61,8 @@ extern void pushtype(unsigned char mod); extern unsigned char btype(unsigned char, unsigned char tok); extern void new_ctx(struct symctx *ctx); extern void del_ctx(void); -extern struct symbol *install(const char *s, unsigned char key); -extern struct symbol *lookup(char *s, unsigned char key); -extern unsigned char hashfun(register const char *s); +extern struct symbol *install(const char *s); +extern struct symbol *lookup(char *s); extern void ctype(struct ctype *cp, unsigned char mod); extern struct ctype *newctype(void); extern void delctype(register struct ctype *tp); diff --git a/tokens.h b/tokens.h @@ -36,7 +36,6 @@ union yyval { extern union yyval yyval; extern char yytext[]; -extern unsigned char yyhash; extern size_t yylen; extern unsigned char yytoken; extern union yyval yyval;