cmd/internal/gc: cache commonly used Ptrto types

Reduces allocations in the compiler by ~1.5%.

No functional changes. Passes toolstash -cmp.

Change-Id: I2416f7fb0aaf9b7d6783c79e840039ad8fa7b5a3
Reviewed-on: https://go-review.googlesource.com/9419
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/src/cmd/internal/gc/subr.go b/src/cmd/internal/gc/subr.go
index 381079e..8cc140a 100644
--- a/src/cmd/internal/gc/subr.go
+++ b/src/cmd/internal/gc/subr.go
@@ -1546,10 +1546,25 @@
 	return binary.LittleEndian.Uint32(h[:4])
 }
 
-func Ptrto(t *Type) *Type {
-	if Tptr == 0 {
-		Fatal("ptrto: no tptr")
-	}
+var initPtrtoDone bool
+
+var (
+	ptrToUint8  *Type
+	ptrToAny    *Type
+	ptrToString *Type
+	ptrToBool   *Type
+	ptrToInt32  *Type
+)
+
+func initPtrto() {
+	ptrToUint8 = ptrto1(Types[TUINT8])
+	ptrToAny = ptrto1(Types[TANY])
+	ptrToString = ptrto1(Types[TSTRING])
+	ptrToBool = ptrto1(Types[TBOOL])
+	ptrToInt32 = ptrto1(Types[TINT32])
+}
+
+func ptrto1(t *Type) *Type {
 	t1 := typ(Tptr)
 	t1.Type = t
 	t1.Width = int64(Widthptr)
@@ -1557,6 +1572,32 @@
 	return t1
 }
 
+// Ptrto returns the Type *t.
+// The returned struct must not be modified.
+func Ptrto(t *Type) *Type {
+	if Tptr == 0 {
+		Fatal("ptrto: no tptr")
+	}
+	// Reduce allocations by pre-creating common cases.
+	if !initPtrtoDone {
+		initPtrto()
+		initPtrtoDone = true
+	}
+	switch t {
+	case Types[TUINT8]:
+		return ptrToUint8
+	case Types[TINT32]:
+		return ptrToInt32
+	case Types[TANY]:
+		return ptrToAny
+	case Types[TSTRING]:
+		return ptrToString
+	case Types[TBOOL]:
+		return ptrToBool
+	}
+	return ptrto1(t)
+}
+
 func frame(context int) {
 	var l *NodeList