shithub: scc

Download patch

ref: a56f57af3f26cde6c17402877b952156c0b3c99e
parent: 4be5b671982310f44410c71e58e88f2f2d8d2ef5
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Dec 12 08:55:58 EST 2016

[cc1] Use circular double list for hash collisions

This new data structure will allow us to remove random
types from any point of the list without problems.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -284,7 +284,6 @@
 	unsigned char align;        /* align of the type */
 	Type *type;                 /* base type */
 	Symbol *tag;                /* symbol of the strug tag */
-	Type *next;                 /* next element in the hash */
 	union {
 		Type **pars;            /* Function type parameters */
 		Symbol **fields;        /* fields of aggregate type */
@@ -293,6 +292,7 @@
 		unsigned char rank;     /* convertion rank */
 		TINT elem;              /* number of type parameters */
 	} n;
+	Type *h_prev, *h_next;       /* hash pointers */
 };
 
 struct symbol {
@@ -356,6 +356,7 @@
 extern Type *duptype(Type *base);
 extern struct limits *getlimits(Type *tp);
 extern void typesize(Type *tp);
+extern void itypes(void);
 
 /* symbol.c */
 extern void dumpstab(char *msg);
--- a/cc1/main.c
+++ b/cc1/main.c
@@ -58,6 +58,7 @@
 	int i;
 
 	atexit(clean);
+	itypes();
 	icpp();
 	ilex();
 
--- a/cc1/types.c
+++ b/cc1/types.c
@@ -72,6 +72,19 @@
 	}
 };
 
+static Type typetab[NR_TYPE_HASH];
+
+void
+itypes()
+{
+	Type *tp;
+
+	for (tp = typetab; tp < &typetab[NR_TYPE_HASH]; ++tp) {
+		tp->h_next = tp;
+		tp->h_prev = tp;
+	}
+}
+
 struct limits *
 getlimits(Type *tp)
 {
@@ -242,8 +255,7 @@
 Type *
 mktype(Type *tp, int op, TINT nelem, Type *pars[])
 {
-	static Type *typetab[NR_TYPE_HASH];
-	Type **tbl, type;
+	Type *tbl, *h_next, type;
 	unsigned t;
 	Type *bp;
 	int c, k_r = 0;
@@ -296,7 +308,7 @@
 
 	t = (op ^ (uintptr_t) tp>>3) & NR_TYPE_HASH-1;
 	tbl = &typetab[t];
-	for (bp = *tbl; bp; bp = bp->next) {
+	for (bp = tbl; bp->h_next != tbl; bp = bp->h_next) {
 		if (eqtype(bp, &type, 0) && op != STRUCT && op != UNION) {
 			/*
 			 * pars was allocated by the caller
@@ -313,8 +325,15 @@
 	bp = xmalloc(sizeof(*bp));
 	*bp = type;
 	bp->id = newid();
-	bp->next = *tbl;
-	return *tbl = bp;
+
+	/* insert the new type in the circular double list */
+	h_next = tbl->h_next;
+	bp->h_next = h_next;
+	bp->h_prev = h_next->h_prev;
+	h_next->h_prev = bp;
+	tbl->h_next = bp;
+
+	return bp;
 }
 
 int