more on dynamic hash in compound literals.
thanks to vskrap, andrey mirtchovski,
and Eoghan Sherry.

R=rsc
CC=golang-dev
https://golang.org/cl/3245041
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index ec73aeb..919d99e 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -1809,14 +1809,11 @@
 }
 
 static int
-prime(ulong h)
+prime(ulong h, ulong sr)
 {
-	ulong n, sr;
+	ulong n;
 
-	sr = h;
-	for(n=0; n<3; n++)
-		sr = (sr + h/sr)/2;
-	for(n=3; n<sr; n+=2)
+	for(n=3; n<=sr; n+=2)
 		if(h%n == 0)
 			return 0;
 	return 1;
@@ -1825,20 +1822,37 @@
 static ulong
 inithash(Node *n, Node ***hash, Node **autohash, ulong nautohash)
 {
-	ulong h;
+	ulong h, sr;
 	NodeList *ll;
+	int i;
 
+	// count the number of entries
 	h = 0;
 	for(ll=n->list; ll; ll=ll->next)
 		h++;
-	h = 9*h/8;
+
+	// if the auto hash table is
+	// large enough use it.
 	if(h <= nautohash) {
 		*hash = autohash;
 		memset(*hash, 0, nautohash * sizeof(**hash));
 		return nautohash;
 	}
-	while(!prime(h))
-		h++;
+
+	// make hash size odd and 12% larger than entries
+	h += h/8;
+	h |= 1;
+
+	// calculate sqrt of h
+	sr = h/2;
+	for(i=0; i<5; i++)
+		sr = (sr + h/sr)/2;
+
+	// check for primeality
+	while(!prime(h, sr))
+		h += 2;
+
+	// build and return a throw-away hash table
 	*hash = mal(h * sizeof(**hash));
 	memset(*hash, 0, h * sizeof(**hash));
 	return h;