@@ -565,7 +565,6 @@ opswitch:
565
565
566
566
n .Right = walkexpr (n .Right , & ll )
567
567
n .Right = addinit (n .Right , ll .Slice ())
568
- n = walkinrange (n , init )
569
568
570
569
case OPRINT , OPRINTN :
571
570
n = walkprint (n , init )
@@ -3523,133 +3522,6 @@ func (n *Node) isIntOrdering() bool {
3523
3522
return n .Left .Type .IsInteger () && n .Right .Type .IsInteger ()
3524
3523
}
3525
3524
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
-
3653
3525
// return 1 if integer n must be in range [0, max), 0 otherwise
3654
3526
func bounded (n * Node , max int64 ) bool {
3655
3527
if n .Type == nil || ! n .Type .IsInteger () {
0 commit comments