summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomer Hsing <homer.xing@intel.com>2012-09-18 16:32:39 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2012-09-26 23:27:00 -0400
commita4cc1c4ed5d7c9ff90b4f14aae09d2792bcbb5e8 (patch)
tree38ecce53f7143c2258c6a8713c81191cd9080725
parent00079e4c041e99f8c686ae2d138c8376e30e7eb3 (diff)
Add a generic hash table algorithm. Reuse for declared_reg_table and label_table in the future.
Rewrite find_register() and insert_register(). The hash table code has been extracted. We may use those code for label table in the future.
-rw-r--r--src/gen4asm.h1
-rw-r--r--src/main.c73
2 files changed, 47 insertions, 27 deletions
diff --git a/src/gen4asm.h b/src/gen4asm.h
index ea498bb..77ef4d5 100644
--- a/src/gen4asm.h
+++ b/src/gen4asm.h
@@ -173,7 +173,6 @@ struct declared_register {
struct region src_region;
int dst_region;
int type;
- struct declared_register *next;
};
struct declared_register *find_register(char *name);
void insert_register(struct declared_register *reg);
diff --git a/src/main.c b/src/main.c
index 6d735e7..edba5c3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -50,9 +50,17 @@ const char const *binary_prepend = "static const char gen_eu_bytes[] = {\n";
struct brw_program compiled_program;
struct program_defaults program_defaults = {.register_type = BRW_REGISTER_TYPE_F};
+#define HASH_SIZE 37
-#define HASHSZ 37
-static struct declared_register *declared_register_table[HASHSZ];
+struct hash_item {
+ char *key;
+ void *value;
+ struct hash_item *next;
+};
+
+typedef struct hash_item *hash_table[HASH_SIZE];
+
+static hash_table declared_register_table;
static const struct option longopts[] = {
{"advanced", no_argument, 0, 'a'},
@@ -76,46 +84,59 @@ static void usage(void)
fprintf(stderr, "\t-g, --gen <4|5|6|7> Specify GPU generation\n");
}
-static int hash(char *name)
+static int hash(char *key)
{
unsigned ret = 0;
- while(*name)
- ret = (ret << 1) + (*name++);
- return ret % HASHSZ;
+ while(*key)
+ ret = (ret << 1) + (*key++);
+ return ret % HASH_SIZE;
}
-struct declared_register *find_register(char *name)
+static void *find_hash_item(hash_table t, char *key)
{
- int index = hash(name);
- struct declared_register *reg;
- for (reg = declared_register_table[index];reg; reg = reg->next)
- if (strcasecmp(reg->name,name) == 0)
- return reg;
+ struct hash_item *p;
+ for(p = t[hash(key)]; p; p = p->next)
+ if(strcasecmp(p->key, key) == 0)
+ return p->value;
return NULL;
}
-void insert_register(struct declared_register *reg)
+static void insert_hash_item(hash_table t, char *key, void *v)
{
- int index = hash(reg->name);
- reg->next = declared_register_table[index];
- declared_register_table[index] = reg;
+ int index = hash(key);
+ struct hash_item *p = malloc(sizeof(*p));
+ p->key = key;
+ p->value = v;
+ p->next = t[index];
+ t[index] = p;
}
-static void free_register_table(void)
+static void free_hash_table(hash_table t)
{
- struct declared_register *reg, *next;
+ struct hash_item *p, *next;
int i;
- for (i = 0; i < HASHSZ; i++) {
- reg = declared_register_table[i];
- while(reg) {
- next = reg->next;
- free(reg->name);
- free(reg);
- reg = next;
+ for (i = 0; i < HASH_SIZE; i++) {
+ p = t[i];
+ while(p) {
+ next = p->next;
+ free(p->key);
+ free(p->value);
+ free(p);
+ p = next;
}
}
}
+struct declared_register *find_register(char *name)
+{
+ return find_hash_item(declared_register_table, name);
+}
+
+void insert_register(struct declared_register *reg)
+{
+ insert_hash_item(declared_register_table, reg->name, reg);
+}
+
struct entry_point_item {
char *str;
struct entry_point_item *next;
@@ -368,7 +389,7 @@ int main(int argc, char **argv)
fprintf(output, "};");
free_entry_point_table(entry_point_table);
- free_register_table();
+ free_hash_table(declared_register_table);
fflush (output);
if (ferror (output)) {
perror ("Could not flush output file");