cmd/compile: cleanup algtype code

Add AlgKind enum type to represent AFOO values.

Add IsComparable, IsRegularMemory, IncomparableField helper methods to
codify common higher-level idioms.

Passes toolstash -cmp.

Change-Id: I54c544953997a8ccc72396b3058897edcbbea392
Reviewed-on: https://go-review.googlesource.com/21420
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index a3e8a04..9310171 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -3020,30 +3020,27 @@
 	// a struct/array containing a non-memory field/element.
 	// Small memory is handled inline, and single non-memory
 	// is handled during type check (OCMPSTR etc).
-	a := algtype1(t, nil)
-
-	if a != AMEM && a != -1 {
-		Fatalf("eqfor %v", t)
-	}
-
-	if a == AMEM {
+	switch a, _ := algtype1(t); a {
+	case AMEM:
 		n := syslook("memequal")
 		n = substArgTypes(n, t, t)
 		*needsize = 1
 		return n
+	case ASPECIAL:
+		sym := typesymprefix(".eq", t)
+		n := newname(sym)
+		n.Class = PFUNC
+		ntype := Nod(OTFUNC, nil, nil)
+		ntype.List.Append(Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
+		ntype.List.Append(Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
+		ntype.Rlist.Append(Nod(ODCLFIELD, nil, typenod(Types[TBOOL])))
+		ntype = typecheck(ntype, Etype)
+		n.Type = ntype.Type
+		*needsize = 0
+		return n
 	}
-
-	sym := typesymprefix(".eq", t)
-	n := newname(sym)
-	n.Class = PFUNC
-	ntype := Nod(OTFUNC, nil, nil)
-	ntype.List.Append(Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
-	ntype.List.Append(Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
-	ntype.Rlist.Append(Nod(ODCLFIELD, nil, typenod(Types[TBOOL])))
-	ntype = typecheck(ntype, Etype)
-	n.Type = ntype.Type
-	*needsize = 0
-	return n
+	Fatalf("eqfor %v", t)
+	return nil
 }
 
 // The result of walkcompare MUST be assigned back to n, e.g.