shithub: scc

Download patch

ref: 2e34f3bcec4662296110dabc00946b06fa8dbd36
parent: 8a27598f9263fb27d738694e6ad87bf37b7f09f3
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Dec 13 12:41:54 EST 2016

[cc1] Remove the circular double list of types

We can apply the same trick we are applying in cc2
and remove the types directly from the hash, because
we do know that it is impossible to have some global
type declared after a local type, and since all
the types are pushed in a stack, poping them
gitves the correct order.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -293,7 +293,7 @@
 		TINT elem;              /* number of type parameters */
 	} n;
 	Type *next;                 /* local list pointer */
-	Type *h_prev, *h_next;       /* hash pointers */
+	Type *h_next;               /* hash collision list */
 };
 
 struct symbol {
@@ -358,7 +358,6 @@
 extern struct limits *getlimits(Type *tp);
 extern void typesize(Type *tp);
 extern void flushtypes(void);
-extern void itypes(void);
 
 /* symbol.c */
 extern void dumpstab(char *msg);
--- a/cc1/types.c
+++ b/cc1/types.c
@@ -10,7 +10,10 @@
 #include "cc1.h"
 
 #define NR_TYPE_HASH 16
+#define HASH(t) (((t)->op ^ (uintptr_t) (t)->type>>3) & NR_TYPE_HASH-1)
 
+static Type *typetab[NR_TYPE_HASH], *localtypes;
+
 /* FIXME:
  * Compiler can generate warnings here if the ranges of TINT,
  * TUINT and TFLOAT are smaller than any of the constants in this
@@ -72,19 +75,6 @@
 	}
 };
 
-static Type typetab[NR_TYPE_HASH], *localtypes;
-
-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)
 {
@@ -260,14 +250,16 @@
 	tp = xmalloc(sizeof(*tp));
 	*tp = *base;
 	tp->id = newid();
+
 	if (curctx > GLOBALCTX+1) {
 		/* it is a type defined in the body of a function */
 		tp->next = localtypes;
 		localtypes = tp;
 	}
-	if (tp->prop & TDEFINED)
+	if (tp->prop & TDEFINED) {
 		typesize(tp);
-	tp->h_next = tp->h_prev = tp;
+		emit(OTYP, tp);
+	}
 	return tp;
 }
 
@@ -274,8 +266,7 @@
 Type *
 mktype(Type *tp, int op, TINT nelem, Type *pars[])
 {
-	Type *tbl, *h_next, type;
-	unsigned t;
+	Type **tbl, type;
 	Type *bp;
 
 	if (op == PTR && tp == voidtype)
@@ -284,10 +275,8 @@
 	memset(&type, 0, sizeof(type));
 	type.type = tp;
 	type.op = op;
-	type.prop = 0;
 	type.p.pars = pars;
 	type.n.elem = nelem;
-	type.ns = 0;
 
 	switch (op) {
 	case ARY:
@@ -324,9 +313,8 @@
 		abort();
 	}
 
-	t = (type.op ^ (uintptr_t) tp>>3) & NR_TYPE_HASH-1;
-	tbl = &typetab[t];
-	for (bp = tbl; bp->h_next != tbl; bp = bp->h_next) {
+	tbl = &typetab[HASH(&type)];
+	for (bp = *tbl; bp; bp = bp->h_next) {
 		if (eqtype(bp, &type, 0)) {
 			/*
 			 * pars was allocated by the caller
@@ -339,11 +327,8 @@
 	}
 
 	bp = newtype(&type);
-	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;
+	bp->h_next = *tbl;
+	*tbl = bp;
 
 	return bp;
 }
@@ -398,9 +383,22 @@
 
 	for (tp = localtypes; tp; tp = next) {
 		next = tp->next;
-		tp->h_prev->h_next = tp->h_next;
-		tp->h_next->h_prev = tp->h_prev;
-		free(tp);
+		switch (tp->op) {
+		default:
+			/*
+			 * All the local types are linked after
+			 * global types, and since we are
+			 * unlinking them in the inverse order
+			 * we do know that tp is always the head
+			 * of the collision list
+			 */
+			typetab[HASH(tp)] = tp->h_next;
+		case STRUCT:
+		case UNION:
+		case ENUM:
+			free(tp);
+			break;
+		}
 	}
 	localtypes = NULL;
 }