Skip to content

Commit 24343cb

Browse files
committed
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 (e37cc29): 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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Josh Bleecher Snyder <[email protected]>
1 parent 7b0b6c2 commit 24343cb

File tree

1 file changed

+0
-128
lines changed

1 file changed

+0
-128
lines changed

src/cmd/compile/internal/gc/walk.go

Lines changed: 0 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,6 @@ opswitch:
565565

566566
n.Right = walkexpr(n.Right, &ll)
567567
n.Right = addinit(n.Right, ll.Slice())
568-
n = walkinrange(n, init)
569568

570569
case OPRINT, OPRINTN:
571570
n = walkprint(n, init)
@@ -3523,133 +3522,6 @@ func (n *Node) isIntOrdering() bool {
35233522
return n.Left.Type.IsInteger() && n.Right.Type.IsInteger()
35243523
}
35253524

3526-
// walkinrange optimizes integer-in-range checks, such as 4 <= x && x < 10.
3527-
// n must be an OANDAND or OOROR node.
3528-
// The result of walkinrange MUST be assigned back to n, e.g.
3529-
// n.Left = walkinrange(n.Left)
3530-
func walkinrange(n *Node, init *Nodes) *Node {
3531-
// We are looking for something equivalent to a opl b OP b opr c, where:
3532-
// * a, b, and c have integer type
3533-
// * b is side-effect-free
3534-
// * opl and opr are each < or ≤
3535-
// * OP is &&
3536-
l := n.Left
3537-
r := n.Right
3538-
if !l.isIntOrdering() || !r.isIntOrdering() {
3539-
return n
3540-
}
3541-
3542-
// Find b, if it exists, and rename appropriately.
3543-
// Input is: l.Left l.Op l.Right ANDAND/OROR r.Left r.Op r.Right
3544-
// Output is: a opl b(==x) ANDAND/OROR b(==x) opr c
3545-
a, opl, b := l.Left, l.Op, l.Right
3546-
x, opr, c := r.Left, r.Op, r.Right
3547-
for i := 0; ; i++ {
3548-
if samesafeexpr(b, x) {
3549-
break
3550-
}
3551-
if i == 3 {
3552-
// Tried all permutations and couldn't find an appropriate b == x.
3553-
return n
3554-
}
3555-
if i&1 == 0 {
3556-
a, opl, b = b, brrev(opl), a
3557-
} else {
3558-
x, opr, c = c, brrev(opr), x
3559-
}
3560-
}
3561-
3562-
// If n.Op is ||, apply de Morgan.
3563-
// Negate the internal ops now; we'll negate the top level op at the end.
3564-
// Henceforth assume &&.
3565-
negateResult := n.Op == OOROR
3566-
if negateResult {
3567-
opl = brcom(opl)
3568-
opr = brcom(opr)
3569-
}
3570-
3571-
cmpdir := func(o Op) int {
3572-
switch o {
3573-
case OLE, OLT:
3574-
return -1
3575-
case OGE, OGT:
3576-
return +1
3577-
}
3578-
Fatalf("walkinrange cmpdir %v", o)
3579-
return 0
3580-
}
3581-
if cmpdir(opl) != cmpdir(opr) {
3582-
// Not a range check; something like b < a && b < c.
3583-
return n
3584-
}
3585-
3586-
switch opl {
3587-
case OGE, OGT:
3588-
// We have something like a > b && b ≥ c.
3589-
// Switch and reverse ops and rename constants,
3590-
// to make it look like a ≤ b && b < c.
3591-
a, c = c, a
3592-
opl, opr = brrev(opr), brrev(opl)
3593-
}
3594-
3595-
// We must ensure that c-a is non-negative.
3596-
// For now, require a and c to be constants.
3597-
// In the future, we could also support a == 0 and c == len/cap(...).
3598-
// Unfortunately, by this point, most len/cap expressions have been
3599-
// stored into temporary variables.
3600-
if !Isconst(a, CTINT) || !Isconst(c, CTINT) {
3601-
return n
3602-
}
3603-
3604-
// Ensure that Int64() does not overflow on a and c (it'll happen
3605-
// for any const above 2**63; see issue #27143).
3606-
if !a.CanInt64() || !c.CanInt64() {
3607-
return n
3608-
}
3609-
3610-
if opl == OLT {
3611-
// We have a < b && ...
3612-
// We need a ≤ b && ... to safely use unsigned comparison tricks.
3613-
// If a is not the maximum constant for b's type,
3614-
// we can increment a and switch to ≤.
3615-
if a.Int64() >= maxintval[b.Type.Etype].Int64() {
3616-
return n
3617-
}
3618-
a = nodintconst(a.Int64() + 1)
3619-
opl = OLE
3620-
}
3621-
3622-
bound := c.Int64() - a.Int64()
3623-
if bound < 0 {
3624-
// Bad news. Something like 5 <= x && x < 3.
3625-
// Rare in practice, and we still need to generate side-effects,
3626-
// so just leave it alone.
3627-
return n
3628-
}
3629-
3630-
// We have a ≤ b && b < c (or a ≤ b && b ≤ c).
3631-
// This is equivalent to (a-a) ≤ (b-a) && (b-a) < (c-a),
3632-
// which is equivalent to 0 ≤ (b-a) && (b-a) < (c-a),
3633-
// which is equivalent to uint(b-a) < uint(c-a).
3634-
ut := b.Type.ToUnsigned()
3635-
lhs := conv(nod(OSUB, b, a), ut)
3636-
rhs := nodintconst(bound)
3637-
if negateResult {
3638-
// Negate top level.
3639-
opr = brcom(opr)
3640-
}
3641-
cmp := nod(opr, lhs, rhs)
3642-
cmp.Pos = n.Pos
3643-
cmp = addinit(cmp, l.Ninit.Slice())
3644-
cmp = addinit(cmp, r.Ninit.Slice())
3645-
// Typecheck the AST rooted at cmp...
3646-
cmp = typecheck(cmp, ctxExpr)
3647-
// ...but then reset cmp's type to match n's type.
3648-
cmp.Type = n.Type
3649-
cmp = walkexpr(cmp, init)
3650-
return cmp
3651-
}
3652-
36533525
// return 1 if integer n must be in range [0, max), 0 otherwise
36543526
func bounded(n *Node, max int64) bool {
36553527
if n.Type == nil || !n.Type.IsInteger() {

0 commit comments

Comments
 (0)