]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove walkinrange optimization
authorMichael Munday <mike.munday@ibm.com>
Tue, 3 Mar 2020 12:44:19 +0000 (12:44 +0000)
committerMichael Munday <mike.munday@ibm.com>
Tue, 3 Mar 2020 19:53:02 +0000 (19:53 +0000)
The walkinrange optimization has been superseded by CL 165998.

Has a small positive impact on binary sizes:

compilecmp master -> HEAD
master (e37cc29863): cmd/compile: optimize integer-in-range checks
HEAD (1a70680a34): cmd/compile: remove walkinrange optimization
platform: linux/amd64

file      before    after     Δ       %
addr2line 4329144   4325048   -4096   -0.095%
api       6060970   6056874   -4096   -0.068%
asm       5196905   5192809   -4096   -0.079%
cgo       4898769   4890577   -8192   -0.167%
compile   20222193  20209713  -12480  -0.062%
cover     5331580   5323388   -8192   -0.154%
dist      3732778   3728682   -4096   -0.110%
doc       4748488   4740296   -8192   -0.173%
link      6707380   6695092   -12288  -0.183%
nm        4278685   4274589   -4096   -0.096%
pack      2305038   2300942   -4096   -0.178%
pprof     14874834  14870738  -4096   -0.028%
test2json 2849221   2845125   -4096   -0.144%
vet       8393173   8384981   -8192   -0.098%
go        15205572  15193284  -12288  -0.081%
total     131812292 131709700 -102592 -0.078%

Updates #30645.

Change-Id: I42d74481652c90fef1a9bc58c70836e42c9b1c4b
Reviewed-on: https://go-review.googlesource.com/c/go/+/221802
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/cmd/compile/internal/gc/walk.go

index 9298d7b783406d437923edda3edfd55de6dcebf2..d468f241f9c7740ec0998193672c49c5eab7176e 100644 (file)
@@ -565,7 +565,6 @@ opswitch:
 
                n.Right = walkexpr(n.Right, &ll)
                n.Right = addinit(n.Right, ll.Slice())
-               n = walkinrange(n, init)
 
        case OPRINT, OPRINTN:
                n = walkprint(n, init)
@@ -3523,133 +3522,6 @@ func (n *Node) isIntOrdering() bool {
        return n.Left.Type.IsInteger() && n.Right.Type.IsInteger()
 }
 
-// walkinrange optimizes integer-in-range checks, such as 4 <= x && x < 10.
-// n must be an OANDAND or OOROR node.
-// The result of walkinrange MUST be assigned back to n, e.g.
-//     n.Left = walkinrange(n.Left)
-func walkinrange(n *Node, init *Nodes) *Node {
-       // We are looking for something equivalent to a opl b OP b opr c, where:
-       // * a, b, and c have integer type
-       // * b is side-effect-free
-       // * opl and opr are each < or ≤
-       // * OP is &&
-       l := n.Left
-       r := n.Right
-       if !l.isIntOrdering() || !r.isIntOrdering() {
-               return n
-       }
-
-       // Find b, if it exists, and rename appropriately.
-       // Input is: l.Left l.Op l.Right ANDAND/OROR r.Left r.Op r.Right
-       // Output is: a opl b(==x) ANDAND/OROR b(==x) opr c
-       a, opl, b := l.Left, l.Op, l.Right
-       x, opr, c := r.Left, r.Op, r.Right
-       for i := 0; ; i++ {
-               if samesafeexpr(b, x) {
-                       break
-               }
-               if i == 3 {
-                       // Tried all permutations and couldn't find an appropriate b == x.
-                       return n
-               }
-               if i&1 == 0 {
-                       a, opl, b = b, brrev(opl), a
-               } else {
-                       x, opr, c = c, brrev(opr), x
-               }
-       }
-
-       // If n.Op is ||, apply de Morgan.
-       // Negate the internal ops now; we'll negate the top level op at the end.
-       // Henceforth assume &&.
-       negateResult := n.Op == OOROR
-       if negateResult {
-               opl = brcom(opl)
-               opr = brcom(opr)
-       }
-
-       cmpdir := func(o Op) int {
-               switch o {
-               case OLE, OLT:
-                       return -1
-               case OGE, OGT:
-                       return +1
-               }
-               Fatalf("walkinrange cmpdir %v", o)
-               return 0
-       }
-       if cmpdir(opl) != cmpdir(opr) {
-               // Not a range check; something like b < a && b < c.
-               return n
-       }
-
-       switch opl {
-       case OGE, OGT:
-               // We have something like a > b && b ≥ c.
-               // Switch and reverse ops and rename constants,
-               // to make it look like a ≤ b && b < c.
-               a, c = c, a
-               opl, opr = brrev(opr), brrev(opl)
-       }
-
-       // We must ensure that c-a is non-negative.
-       // For now, require a and c to be constants.
-       // In the future, we could also support a == 0 and c == len/cap(...).
-       // Unfortunately, by this point, most len/cap expressions have been
-       // stored into temporary variables.
-       if !Isconst(a, CTINT) || !Isconst(c, CTINT) {
-               return n
-       }
-
-       // Ensure that Int64() does not overflow on a and c (it'll happen
-       // for any const above 2**63; see issue #27143).
-       if !a.CanInt64() || !c.CanInt64() {
-               return n
-       }
-
-       if opl == OLT {
-               // We have a < b && ...
-               // We need a ≤ b && ... to safely use unsigned comparison tricks.
-               // If a is not the maximum constant for b's type,
-               // we can increment a and switch to ≤.
-               if a.Int64() >= maxintval[b.Type.Etype].Int64() {
-                       return n
-               }
-               a = nodintconst(a.Int64() + 1)
-               opl = OLE
-       }
-
-       bound := c.Int64() - a.Int64()
-       if bound < 0 {
-               // Bad news. Something like 5 <= x && x < 3.
-               // Rare in practice, and we still need to generate side-effects,
-               // so just leave it alone.
-               return n
-       }
-
-       // We have a ≤ b && b < c (or a ≤ b && b ≤ c).
-       // This is equivalent to (a-a) ≤ (b-a) && (b-a) < (c-a),
-       // which is equivalent to 0 ≤ (b-a) && (b-a) < (c-a),
-       // which is equivalent to uint(b-a) < uint(c-a).
-       ut := b.Type.ToUnsigned()
-       lhs := conv(nod(OSUB, b, a), ut)
-       rhs := nodintconst(bound)
-       if negateResult {
-               // Negate top level.
-               opr = brcom(opr)
-       }
-       cmp := nod(opr, lhs, rhs)
-       cmp.Pos = n.Pos
-       cmp = addinit(cmp, l.Ninit.Slice())
-       cmp = addinit(cmp, r.Ninit.Slice())
-       // Typecheck the AST rooted at cmp...
-       cmp = typecheck(cmp, ctxExpr)
-       // ...but then reset cmp's type to match n's type.
-       cmp.Type = n.Type
-       cmp = walkexpr(cmp, init)
-       return cmp
-}
-
 // return 1 if integer n must be in range [0, max), 0 otherwise
 func bounded(n *Node, max int64) bool {
        if n.Type == nil || !n.Type.IsInteger() {