From 1cc7be89a94951cbd1b6db669cb5a278e7aea545 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 24 Apr 2020 11:01:38 -0700 Subject: [PATCH] cmd/compile: improve generated eq algs for structs containing interfaces type T struct { s interface{} i int } Prior to this change, we generated this equality algorithm for T: func eqT(p, q *T) bool { return p.s.type == q.s.type && runtime.efaceeq(p.s.type, p.s.data, q.s.data) && p.i == q.i } This change splits the two halves of the interface equality, so that we can do the cheap (type) half early and the expensive (data) half late. We now generate: func eqT(p, q *T) bool { return p.s.type == q.s.type && p.i == q.i && runtime.efaceeq(p.s.type, p.s.data, q.s.data) } The generated code tends to be a bit smaller. Examples: go/ast .eq."".ForStmt 306 -> 304 (-0.65%) .eq."".TypeAssertExpr 221 -> 219 (-0.90%) .eq."".TypeSwitchStmt 228 -> 226 (-0.88%) .eq."".ParenExpr 150 -> 148 (-1.33%) .eq."".IndexExpr 221 -> 219 (-0.90%) .eq."".SwitchStmt 228 -> 226 (-0.88%) .eq."".RangeStmt 334 -> 332 (-0.60%) Change-Id: Iec9e24f214ca772416202b9fb9252e625c22380e Reviewed-on: https://go-review.googlesource.com/c/go/+/230207 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/gc/alg.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go index 16524773a06..571ac4c6c7b 100644 --- a/src/cmd/compile/internal/gc/alg.go +++ b/src/cmd/compile/internal/gc/alg.go @@ -585,6 +585,14 @@ func geneq(t *types.Type) *obj.LSym { eqlen, eqmem := eqstring(p, q) and(eqlen) and(eqmem) + case f.Type.IsInterface(): + p.Type = f.Type + p = typecheck(p, ctxExpr) + q.Type = f.Type + q = typecheck(q, ctxExpr) + eqtab, eqdata := eqinterface(p, q) + and(eqtab) + and(eqdata) default: and(nod(OEQ, p, q)) }