From 59e55834ed447f35b8bfb08faee7077cf66a7d94 Mon Sep 17 00:00:00 2001 From: Bill Currie <bill@taniwha.org> Date: Sun, 1 Apr 2001 06:01:02 +0000 Subject: [PATCH] Another massive speadup caused by using hash tables to lookup already generated immediate values. frikbot now compiles in just over 1s on my machine. --- tools/qfcc/include/qfcc.h | 1 + tools/qfcc/source/Makefile.am | 2 +- tools/qfcc/source/pr_comp.c | 59 --------------- tools/qfcc/source/pr_def.c | 2 +- tools/qfcc/source/pr_imm.c | 132 ++++++++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 61 deletions(-) create mode 100644 tools/qfcc/source/pr_imm.c diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index bc76df920..88e871fa5 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -356,6 +356,7 @@ void PR_Lex (void); type_t *PR_ParseType (void); char *PR_ParseName (void); +def_t *PR_ParseImmediate (void); qboolean PR_Check (token_type_t type, char *string); void PR_Expect (token_type_t type, char *string); diff --git a/tools/qfcc/source/Makefile.am b/tools/qfcc/source/Makefile.am index 4581588ce..7f4060b42 100644 --- a/tools/qfcc/source/Makefile.am +++ b/tools/qfcc/source/Makefile.am @@ -32,5 +32,5 @@ INCLUDES= -I$(top_srcdir)/include bin_PROGRAMS= qfcc -qfcc_SOURCES= cmdlib.c pr_comp.c pr_def.c pr_lex.c qfcc.c +qfcc_SOURCES= cmdlib.c pr_comp.c pr_def.c pr_imm.c pr_lex.c qfcc.c qfcc_LDADD= -lQFutil diff --git a/tools/qfcc/source/pr_comp.c b/tools/qfcc/source/pr_comp.c index c0763b687..5d7339b56 100644 --- a/tools/qfcc/source/pr_comp.c +++ b/tools/qfcc/source/pr_comp.c @@ -182,65 +182,6 @@ PR_Statement (opcode_t * op, def_t * var_a, def_t * var_b) return var_c; } -/* - PR_ParseImmediate - - Looks for a preexisting constant -*/ -def_t * -PR_ParseImmediate (void) -{ - def_t *cn; - - // check for a constant with the same value - for (cn = pr.def_head.next; cn; cn = cn->next) { - if (!cn->initialized) - continue; - if (cn->type != pr_immediate_type) - continue; - if (pr_immediate_type == &type_string) { - if (!strcmp (G_STRING (cn->ofs), pr_immediate_string)) { - PR_Lex (); - return cn; - } - } else if (pr_immediate_type == &type_float) { - if (G_FLOAT (cn->ofs) == pr_immediate._float) { - PR_Lex (); - return cn; - } - } else if (pr_immediate_type == &type_vector) { - if ((G_FLOAT (cn->ofs) == pr_immediate.vector[0]) - && (G_FLOAT (cn->ofs + 1) == pr_immediate.vector[1]) - && (G_FLOAT (cn->ofs + 2) == pr_immediate.vector[2])) { - PR_Lex (); - return cn; - } - } else { - PR_ParseError ("weird immediate type"); - } - } - - // allocate a new one - // always share immediates - cn = PR_NewDef (pr_immediate_type, "IMMEDIATE", 0); - cn->initialized = 1; - cn->scope = NULL; - - // copy the immediate to the global area - cn->ofs = numpr_globals; - pr_global_defs[cn->ofs] = cn; - numpr_globals += type_size[pr_immediate_type->type]; - if (pr_immediate_type == &type_string) - pr_immediate.string = CopyString (pr_immediate_string); - - memcpy (pr_globals + cn->ofs, &pr_immediate, - 4 * type_size[pr_immediate_type->type]); - - PR_Lex (); - - return cn; -} - void PrecacheSound (def_t *e, int ch) diff --git a/tools/qfcc/source/pr_def.c b/tools/qfcc/source/pr_def.c index a0c50eb56..d3366d0f7 100644 --- a/tools/qfcc/source/pr_def.c +++ b/tools/qfcc/source/pr_def.c @@ -28,7 +28,7 @@ def_t *pr_global_defs[MAX_REGS]; // to find def for a global variable int pr_edict_size; -hashtab_t *defs_by_name; +static hashtab_t *defs_by_name; static char * defs_get_key (void *_def, void *_tab) diff --git a/tools/qfcc/source/pr_imm.c b/tools/qfcc/source/pr_imm.c new file mode 100644 index 000000000..11c066b05 --- /dev/null +++ b/tools/qfcc/source/pr_imm.c @@ -0,0 +1,132 @@ +/* Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + See file, 'COPYING', for details. +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "QF/hash.h" + +#include "qfcc.h" + +static hashtab_t *string_imm_defs; +static hashtab_t *float_imm_defs; +static hashtab_t *vector_imm_defs; + +static char * +string_imm_get_key (void *_def, void *unused) +{ + def_t *def = (def_t*)_def; + return G_STRING (def->ofs); +} + +static char * +float_imm_get_key (void *_def, void *unused) +{ + def_t *def = (def_t*)_def; + static char rep[20]; + sprintf (rep, "\001float:%08X\001", G_INT(def->ofs)); + return rep; +} + +static char * +vector_imm_get_key (void *_def, void *unused) +{ + def_t *def = (def_t*)_def; + static char rep[60]; + sprintf (rep, "\001vector:%08X\001%08X\001%08X\001", + G_INT(def->ofs), G_INT(def->ofs+1), G_INT(def->ofs+1)); + return rep; +} + +/* + PR_ParseImmediate + + Looks for a preexisting constant +*/ +def_t * +PR_ParseImmediate (void) +{ + def_t *cn = 0; + char rep[60]; + hashtab_t *tab = 0; + + if (!string_imm_defs) { + string_imm_defs = Hash_NewTable (1021, string_imm_get_key, 0, 0); + float_imm_defs = Hash_NewTable (1021, float_imm_get_key, 0, 0); + vector_imm_defs = Hash_NewTable (1021, vector_imm_get_key, 0, 0); + } + if (pr_immediate_type == &type_string) { + cn = (def_t*) Hash_Find (string_imm_defs, pr_immediate_string); + tab = string_imm_defs; + //printf ("%s\n",pr_immediate_string); + } else if (pr_immediate_type == &type_float) { + sprintf (rep, "\001float:%08X\001", *(int*)&pr_immediate._float); + cn = (def_t*) Hash_Find (float_imm_defs, rep); + tab = float_imm_defs; + //printf ("%f\n",pr_immediate._float); + } else if (pr_immediate_type == &type_vector) { + sprintf (rep, "\001vector:%08X\001%08X\001%08X\001", + *(int*)&pr_immediate.vector[0], + *(int*)&pr_immediate.vector[1], + *(int*)&pr_immediate.vector[2]); + cn = (def_t*) Hash_Find (vector_imm_defs, rep); + tab = vector_imm_defs; + //printf ("%f %f %f\n",pr_immediate.vector[0], pr_immediate.vector[1], pr_immediate.vector[2]); + } else { + PR_ParseError ("weird immediate type"); + } + if (cn) { + if (cn->type != pr_immediate_type) printf("urk\n"); + //printf("found\n"); + PR_Lex (); + return cn; + } + + // allocate a new one + // always share immediates + cn = PR_NewDef (pr_immediate_type, "IMMEDIATE", 0); + cn->initialized = 1; + + // copy the immediate to the global area + cn->ofs = numpr_globals; + pr_global_defs[cn->ofs] = cn; + numpr_globals += type_size[pr_immediate_type->type]; + if (pr_immediate_type == &type_string) + pr_immediate.string = CopyString (pr_immediate_string); + + memcpy (pr_globals + cn->ofs, &pr_immediate, + 4 * type_size[pr_immediate_type->type]); + + Hash_Add (tab, cn); + + if (pr_immediate_type == &type_vector) { + int i; + + for (i = 0; i < 3; i++) { + def_t *d = PR_NewDef (&type_float, "IMMEDIATE", 0); + d->initialized = 1; + d->ofs = cn->ofs + i; + Hash_Add (float_imm_defs, d); + } + } + + PR_Lex (); + + return cn; +}