]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: refactor out eqstring
authorJosh Bleecher Snyder <josharian@gmail.com>
Fri, 24 Apr 2020 16:43:49 +0000 (09:43 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 27 Apr 2020 17:19:07 +0000 (17:19 +0000)
Refactor out creating the two Nodes needed to check string equality.
Preliminary work to other optimizations.

Passes toolstash-check.

Change-Id: I72e824dac904e579b8ba9a3669a94fa1471112d2
Reviewed-on: https://go-review.googlesource.com/c/go/+/230204
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 fcf14768fbdc222c13a00905ecf1886dc506f0bb..1130a4c17bc9b3add6d1ff6a6ae86f1b85d50bad 100644 (file)
@@ -664,6 +664,32 @@ func eqfield(p *Node, q *Node, field *types.Sym) *Node {
        return ne
 }
 
+// eqstring returns the nodes
+//   len(s) == len(t)
+// and
+//   memequal(s.ptr, t.ptr, len(s))
+// which can be used to construct string equality comparison.
+// eqlen must be evaluated before eqmem, and shortcircuiting is required.
+func eqstring(s, t *Node) (eqlen, eqmem *Node) {
+       s = conv(s, types.Types[TSTRING])
+       t = conv(t, types.Types[TSTRING])
+       sptr := nod(OSPTR, s, nil)
+       tptr := nod(OSPTR, t, nil)
+       slen := conv(nod(OLEN, s, nil), types.Types[TUINTPTR])
+       tlen := conv(nod(OLEN, t, nil), types.Types[TUINTPTR])
+
+       fn := syslook("memequal")
+       fn = substArgTypes(fn, types.Types[TUINT8], types.Types[TUINT8])
+       call := nod(OCALL, fn, nil)
+       call.List.Append(sptr, tptr, slen.copy())
+       call = typecheck(call, ctxExpr|ctxMultiOK)
+
+       cmp := nod(OEQ, slen, tlen)
+       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 8589c3e72b5f89c086e340bf834c12699d2c800b..5dd98efc75994685580a857bba4d830e4b346631 100644 (file)
@@ -3518,27 +3518,16 @@ func walkcompareString(n *Node, init *Nodes) *Node {
                // prepare for rewrite below
                n.Left = cheapexpr(n.Left, init)
                n.Right = cheapexpr(n.Right, init)
-
-               lstr := conv(n.Left, types.Types[TSTRING])
-               rstr := conv(n.Right, types.Types[TSTRING])
-               lptr := nod(OSPTR, lstr, nil)
-               rptr := nod(OSPTR, rstr, nil)
-               llen := conv(nod(OLEN, lstr, nil), types.Types[TUINTPTR])
-               rlen := conv(nod(OLEN, rstr, nil), types.Types[TUINTPTR])
-
-               fn := syslook("memequal")
-               fn = substArgTypes(fn, types.Types[TUINT8], types.Types[TUINT8])
-               r = mkcall1(fn, types.Types[TBOOL], init, lptr, rptr, llen)
-
+               eqlen, eqmem := eqstring(n.Left, n.Right)
                // quick check of len before full compare for == or !=.
                // memequal then tests equality up to length len.
                if n.Op == OEQ {
                        // len(left) == len(right) && memequal(left, right, len)
-                       r = nod(OANDAND, nod(OEQ, llen, rlen), r)
+                       r = nod(OANDAND, eqlen, eqmem)
                } else {
                        // len(left) != len(right) || !memequal(left, right, len)
-                       r = nod(ONOT, r, nil)
-                       r = nod(OOROR, nod(ONE, llen, rlen), r)
+                       eqlen.Op = ONE
+                       r = nod(OOROR, eqlen, nod(ONOT, eqmem, nil))
                }
        } else {
                // sys_cmpstring(s1, s2) :: 0