]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: refactor out eqinterface
authorJosh Bleecher Snyder <josharian@gmail.com>
Fri, 24 Apr 2020 18:00:44 +0000 (11:00 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 27 Apr 2020 17:19:27 +0000 (17:19 +0000)
Refactor out creating the two Nodes needed to check interface equality.
Preliminary work to other optimizations.

Passes toolstash-check.

Change-Id: Id6b39e8e78f07289193423d0ef905d70826acf89
Reviewed-on: https://go-review.googlesource.com/c/go/+/230206
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/walk.go

index 33e8eca54e88f9194b9db88940dec087f92e234d..16524773a06158b3662386bea99caa75706b8a21 100644 (file)
@@ -699,6 +699,44 @@ func eqstring(s, t *Node) (eqlen, eqmem *Node) {
        return cmp, call
 }
 
+// eqinterface returns the nodes
+//   s.tab == t.tab (or s.typ == t.typ, as appropriate)
+// and
+//   ifaceeq(s.tab, s.data, t.data) (or efaceeq(s.typ, s.data, t.data), as appropriate)
+// which can be used to construct interface equality comparison.
+// eqtab must be evaluated before eqdata, and shortcircuiting is required.
+func eqinterface(s, t *Node) (eqtab, eqdata *Node) {
+       if !types.Identical(s.Type, t.Type) {
+               Fatalf("eqinterface %v %v", s.Type, t.Type)
+       }
+       // func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
+       // func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
+       var fn *Node
+       if s.Type.IsEmptyInterface() {
+               fn = syslook("efaceeq")
+       } else {
+               fn = syslook("ifaceeq")
+       }
+
+       stab := nod(OITAB, s, nil)
+       ttab := nod(OITAB, t, nil)
+       sdata := nod(OIDATA, s, nil)
+       tdata := nod(OIDATA, t, nil)
+       sdata.Type = types.Types[TUNSAFEPTR]
+       tdata.Type = types.Types[TUNSAFEPTR]
+       sdata.SetTypecheck(1)
+       tdata.SetTypecheck(1)
+
+       call := nod(OCALL, fn, nil)
+       call.List.Append(stab, sdata, tdata)
+       call = typecheck(call, ctxExpr|ctxMultiOK)
+
+       cmp := nod(OEQ, stab, ttab)
+       cmp = typecheck(cmp, ctxExpr)
+       cmp.Type = types.Types[TBOOL]
+       return cmp, call
+}
+
 // eqmem returns the node
 //     memequal(&p.field, &q.field [, size])
 func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node {
index 5dd98efc75994685580a857bba4d830e4b346631..84ba528bc9674ade36a2583949b58790ecdc48bf 100644 (file)
@@ -3379,36 +3379,15 @@ func tracecmpArg(n *Node, t *types.Type, init *Nodes) *Node {
 }
 
 func walkcompareInterface(n *Node, init *Nodes) *Node {
-       // ifaceeq(i1 any-1, i2 any-2) (ret bool);
-       if !types.Identical(n.Left.Type, n.Right.Type) {
-               Fatalf("ifaceeq %v %v %v", n.Op, n.Left.Type, n.Right.Type)
-       }
-       var fn *Node
-       if n.Left.Type.IsEmptyInterface() {
-               fn = syslook("efaceeq")
-       } else {
-               fn = syslook("ifaceeq")
-       }
-
        n.Right = cheapexpr(n.Right, init)
        n.Left = cheapexpr(n.Left, init)
-       lt := nod(OITAB, n.Left, nil)
-       rt := nod(OITAB, n.Right, nil)
-       ld := nod(OIDATA, n.Left, nil)
-       rd := nod(OIDATA, n.Right, nil)
-       ld.Type = types.Types[TUNSAFEPTR]
-       rd.Type = types.Types[TUNSAFEPTR]
-       ld.SetTypecheck(1)
-       rd.SetTypecheck(1)
-       call := mkcall1(fn, n.Type, init, lt, ld, rd)
-
-       // Check itable/type before full compare.
-       // Note: short-circuited because order matters.
+       eqtab, eqdata := eqinterface(n.Left, n.Right)
        var cmp *Node
        if n.Op == OEQ {
-               cmp = nod(OANDAND, nod(OEQ, lt, rt), call)
+               cmp = nod(OANDAND, eqtab, eqdata)
        } else {
-               cmp = nod(OOROR, nod(ONE, lt, rt), nod(ONOT, call, nil))
+               eqtab.Op = ONE
+               cmp = nod(OOROR, eqtab, nod(ONOT, eqdata, nil))
        }
        return finishcompare(n, cmp, init)
 }