Add a generic hash table algorithm. Reuse for declared_reg_table and label_table...
authorHomer Hsing <homer.xing@intel.com>
Tue, 18 Sep 2012 08:32:39 +0000 (16:32 +0800)
committerDamien Lespiau <damien.lespiau@intel.com>
Mon, 4 Mar 2013 15:54:32 +0000 (15:54 +0000)
Rewrite find_register() and insert_register(). The hash table code
has been extracted. We may use those code for label table in the future.

assembler/src/gen4asm.h
assembler/src/main.c

index ea498bb..77ef4d5 100644 (file)
@@ -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);
index 6d735e7..edba5c3 100644 (file)
@@ -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");