cmd/compile: remove walkinrange optimization

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>
This commit is contained in:
Michael Munday 2020-03-03 12:44:19 +00:00
parent 7b0b6c2f7e
commit 24343cb886
1 changed files with 0 additions and 128 deletions

View 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() {