Skip to content

Commit 47d2a4d

Browse files
committed
cmd/compile: remove walkmul
Replace with generic rewrite rules. Change-Id: I3ee32076cfd9db5801f1a7bdbb73a994255884a9 Reviewed-on: https://go-review.googlesource.com/36323 Run-TryBot: Josh Bleecher Snyder <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 6aee6b8 commit 47d2a4d

File tree

3 files changed

+198
-80
lines changed

3 files changed

+198
-80
lines changed

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

Lines changed: 8 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -542,23 +542,26 @@ opswitch:
542542
Warn("shift bounds check elided")
543543
}
544544

545-
// Use results from call expression as arguments for complex.
546545
case OAND,
547546
OSUB,
548547
OHMUL,
548+
OMUL,
549549
OLT,
550550
OLE,
551551
OGE,
552552
OGT,
553553
OADD,
554554
OOR,
555-
OXOR,
556-
OCOMPLEX:
557-
if n.Op == OCOMPLEX && n.Left == nil && n.Right == nil {
555+
OXOR:
556+
n.Left = walkexpr(n.Left, init)
557+
n.Right = walkexpr(n.Right, init)
558+
559+
case OCOMPLEX:
560+
// Use results from call expression as arguments for complex.
561+
if n.Left == nil && n.Right == nil {
558562
n.Left = n.List.First()
559563
n.Right = n.List.Second()
560564
}
561-
562565
n.Left = walkexpr(n.Left, init)
563566
n.Right = walkexpr(n.Right, init)
564567

@@ -1071,11 +1074,6 @@ opswitch:
10711074
n.Right = typecheck(n.Right, Erv)
10721075
n.Right = walkexpr(n.Right, init)
10731076

1074-
case OMUL:
1075-
n.Left = walkexpr(n.Left, init)
1076-
n.Right = walkexpr(n.Right, init)
1077-
n = walkmul(n, init)
1078-
10791077
case ODIV, OMOD:
10801078
n.Left = walkexpr(n.Left, init)
10811079
n.Right = walkexpr(n.Right, init)
@@ -3398,76 +3396,6 @@ func walkinrange(n *Node, init *Nodes) *Node {
33983396
return cmp
33993397
}
34003398

3401-
// walkmul rewrites integer multiplication by powers of two as shifts.
3402-
// The result of walkmul MUST be assigned back to n, e.g.
3403-
// n.Left = walkmul(n.Left, init)
3404-
func walkmul(n *Node, init *Nodes) *Node {
3405-
if !n.Type.IsInteger() {
3406-
return n
3407-
}
3408-
3409-
var nr *Node
3410-
var nl *Node
3411-
if n.Right.Op == OLITERAL {
3412-
nl = n.Left
3413-
nr = n.Right
3414-
} else if n.Left.Op == OLITERAL {
3415-
nl = n.Right
3416-
nr = n.Left
3417-
} else {
3418-
return n
3419-
}
3420-
3421-
neg := 0
3422-
3423-
// x*0 is 0 (and side effects of x).
3424-
var pow int
3425-
var w int
3426-
if nr.Int64() == 0 {
3427-
cheapexpr(nl, init)
3428-
Nodconst(n, n.Type, 0)
3429-
goto ret
3430-
}
3431-
3432-
// nr is a constant.
3433-
pow = powtwo(nr)
3434-
3435-
if pow < 0 {
3436-
return n
3437-
}
3438-
if pow >= 1000 {
3439-
// negative power of 2, like -16
3440-
neg = 1
3441-
3442-
pow -= 1000
3443-
}
3444-
3445-
w = int(nl.Type.Width * 8)
3446-
if pow+1 >= w { // too big, shouldn't happen
3447-
return n
3448-
}
3449-
3450-
nl = cheapexpr(nl, init)
3451-
3452-
if pow == 0 {
3453-
// x*1 is x
3454-
n = nl
3455-
3456-
goto ret
3457-
}
3458-
3459-
n = nod(OLSH, nl, nodintconst(int64(pow)))
3460-
3461-
ret:
3462-
if neg != 0 {
3463-
n = nod(OMINUS, n, nil)
3464-
}
3465-
3466-
n = typecheck(n, Erv)
3467-
n = walkexpr(n, init)
3468-
return n
3469-
}
3470-
34713399
// walkdiv rewrites division by a constant as less expensive
34723400
// operations.
34733401
// The result of walkdiv MUST be assigned back to n, e.g.

src/cmd/compile/internal/ssa/gen/generic.rules

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@
120120
(Mul32 (Const32 [-1]) x) -> (Neg32 x)
121121
(Mul64 (Const64 [-1]) x) -> (Neg64 x)
122122

123+
// Convert multiplication by a power of two to a shift.
124+
(Mul8 <t> n (Const8 [c])) && isPowerOfTwo(c) -> (Lsh8x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(c)]))
125+
(Mul16 <t> n (Const16 [c])) && isPowerOfTwo(c) -> (Lsh16x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(c)]))
126+
(Mul32 <t> n (Const32 [c])) && isPowerOfTwo(c) -> (Lsh32x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(c)]))
127+
(Mul64 <t> n (Const64 [c])) && isPowerOfTwo(c) -> (Lsh64x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(c)]))
128+
(Mul8 <t> n (Const8 [c])) && t.IsSigned() && isPowerOfTwo(-c) -> (Neg8 (Lsh8x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(-c)])))
129+
(Mul16 <t> n (Const16 [c])) && t.IsSigned() && isPowerOfTwo(-c) -> (Neg16 (Lsh16x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(-c)])))
130+
(Mul32 <t> n (Const32 [c])) && t.IsSigned() && isPowerOfTwo(-c) -> (Neg32 (Lsh32x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(-c)])))
131+
(Mul64 <t> n (Const64 [c])) && t.IsSigned() && isPowerOfTwo(-c) -> (Neg64 (Lsh64x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(-c)])))
132+
123133
(Mod8 (Const8 [c]) (Const8 [d])) && d != 0 -> (Const8 [int64(int8(c % d))])
124134
(Mod16 (Const16 [c]) (Const16 [d])) && d != 0 -> (Const16 [int64(int16(c % d))])
125135
(Mod32 (Const32 [c]) (Const32 [d])) && d != 0 -> (Const32 [int64(int32(c % d))])

src/cmd/compile/internal/ssa/rewritegeneric.go

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5458,6 +5458,51 @@ func rewriteValuegeneric_OpMul16(v *Value, config *Config) bool {
54585458
v.AddArg(x)
54595459
return true
54605460
}
5461+
// match: (Mul16 <t> n (Const16 [c]))
5462+
// cond: isPowerOfTwo(c)
5463+
// result: (Lsh16x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(c)]))
5464+
for {
5465+
t := v.Type
5466+
n := v.Args[0]
5467+
v_1 := v.Args[1]
5468+
if v_1.Op != OpConst16 {
5469+
break
5470+
}
5471+
c := v_1.AuxInt
5472+
if !(isPowerOfTwo(c)) {
5473+
break
5474+
}
5475+
v.reset(OpLsh16x64)
5476+
v.Type = t
5477+
v.AddArg(n)
5478+
v0 := b.NewValue0(v.Pos, OpConst64, config.fe.TypeUInt64())
5479+
v0.AuxInt = log2(c)
5480+
v.AddArg(v0)
5481+
return true
5482+
}
5483+
// match: (Mul16 <t> n (Const16 [c]))
5484+
// cond: t.IsSigned() && isPowerOfTwo(-c)
5485+
// result: (Neg16 (Lsh16x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(-c)])))
5486+
for {
5487+
t := v.Type
5488+
n := v.Args[0]
5489+
v_1 := v.Args[1]
5490+
if v_1.Op != OpConst16 {
5491+
break
5492+
}
5493+
c := v_1.AuxInt
5494+
if !(t.IsSigned() && isPowerOfTwo(-c)) {
5495+
break
5496+
}
5497+
v.reset(OpNeg16)
5498+
v0 := b.NewValue0(v.Pos, OpLsh16x64, t)
5499+
v0.AddArg(n)
5500+
v1 := b.NewValue0(v.Pos, OpConst64, config.fe.TypeUInt64())
5501+
v1.AuxInt = log2(-c)
5502+
v0.AddArg(v1)
5503+
v.AddArg(v0)
5504+
return true
5505+
}
54615506
// match: (Mul16 x (Const16 <t> [c]))
54625507
// cond: x.Op != OpConst16
54635508
// result: (Mul16 (Const16 <t> [c]) x)
@@ -5533,6 +5578,51 @@ func rewriteValuegeneric_OpMul32(v *Value, config *Config) bool {
55335578
v.AddArg(x)
55345579
return true
55355580
}
5581+
// match: (Mul32 <t> n (Const32 [c]))
5582+
// cond: isPowerOfTwo(c)
5583+
// result: (Lsh32x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(c)]))
5584+
for {
5585+
t := v.Type
5586+
n := v.Args[0]
5587+
v_1 := v.Args[1]
5588+
if v_1.Op != OpConst32 {
5589+
break
5590+
}
5591+
c := v_1.AuxInt
5592+
if !(isPowerOfTwo(c)) {
5593+
break
5594+
}
5595+
v.reset(OpLsh32x64)
5596+
v.Type = t
5597+
v.AddArg(n)
5598+
v0 := b.NewValue0(v.Pos, OpConst64, config.fe.TypeUInt64())
5599+
v0.AuxInt = log2(c)
5600+
v.AddArg(v0)
5601+
return true
5602+
}
5603+
// match: (Mul32 <t> n (Const32 [c]))
5604+
// cond: t.IsSigned() && isPowerOfTwo(-c)
5605+
// result: (Neg32 (Lsh32x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(-c)])))
5606+
for {
5607+
t := v.Type
5608+
n := v.Args[0]
5609+
v_1 := v.Args[1]
5610+
if v_1.Op != OpConst32 {
5611+
break
5612+
}
5613+
c := v_1.AuxInt
5614+
if !(t.IsSigned() && isPowerOfTwo(-c)) {
5615+
break
5616+
}
5617+
v.reset(OpNeg32)
5618+
v0 := b.NewValue0(v.Pos, OpLsh32x64, t)
5619+
v0.AddArg(n)
5620+
v1 := b.NewValue0(v.Pos, OpConst64, config.fe.TypeUInt64())
5621+
v1.AuxInt = log2(-c)
5622+
v0.AddArg(v1)
5623+
v.AddArg(v0)
5624+
return true
5625+
}
55365626
// match: (Mul32 x (Const32 <t> [c]))
55375627
// cond: x.Op != OpConst32
55385628
// result: (Mul32 (Const32 <t> [c]) x)
@@ -5735,6 +5825,51 @@ func rewriteValuegeneric_OpMul64(v *Value, config *Config) bool {
57355825
v.AddArg(x)
57365826
return true
57375827
}
5828+
// match: (Mul64 <t> n (Const64 [c]))
5829+
// cond: isPowerOfTwo(c)
5830+
// result: (Lsh64x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(c)]))
5831+
for {
5832+
t := v.Type
5833+
n := v.Args[0]
5834+
v_1 := v.Args[1]
5835+
if v_1.Op != OpConst64 {
5836+
break
5837+
}
5838+
c := v_1.AuxInt
5839+
if !(isPowerOfTwo(c)) {
5840+
break
5841+
}
5842+
v.reset(OpLsh64x64)
5843+
v.Type = t
5844+
v.AddArg(n)
5845+
v0 := b.NewValue0(v.Pos, OpConst64, config.fe.TypeUInt64())
5846+
v0.AuxInt = log2(c)
5847+
v.AddArg(v0)
5848+
return true
5849+
}
5850+
// match: (Mul64 <t> n (Const64 [c]))
5851+
// cond: t.IsSigned() && isPowerOfTwo(-c)
5852+
// result: (Neg64 (Lsh64x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(-c)])))
5853+
for {
5854+
t := v.Type
5855+
n := v.Args[0]
5856+
v_1 := v.Args[1]
5857+
if v_1.Op != OpConst64 {
5858+
break
5859+
}
5860+
c := v_1.AuxInt
5861+
if !(t.IsSigned() && isPowerOfTwo(-c)) {
5862+
break
5863+
}
5864+
v.reset(OpNeg64)
5865+
v0 := b.NewValue0(v.Pos, OpLsh64x64, t)
5866+
v0.AddArg(n)
5867+
v1 := b.NewValue0(v.Pos, OpConst64, config.fe.TypeUInt64())
5868+
v1.AuxInt = log2(-c)
5869+
v0.AddArg(v1)
5870+
v.AddArg(v0)
5871+
return true
5872+
}
57385873
// match: (Mul64 x (Const64 <t> [c]))
57395874
// cond: x.Op != OpConst64
57405875
// result: (Mul64 (Const64 <t> [c]) x)
@@ -5937,6 +6072,51 @@ func rewriteValuegeneric_OpMul8(v *Value, config *Config) bool {
59376072
v.AddArg(x)
59386073
return true
59396074
}
6075+
// match: (Mul8 <t> n (Const8 [c]))
6076+
// cond: isPowerOfTwo(c)
6077+
// result: (Lsh8x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(c)]))
6078+
for {
6079+
t := v.Type
6080+
n := v.Args[0]
6081+
v_1 := v.Args[1]
6082+
if v_1.Op != OpConst8 {
6083+
break
6084+
}
6085+
c := v_1.AuxInt
6086+
if !(isPowerOfTwo(c)) {
6087+
break
6088+
}
6089+
v.reset(OpLsh8x64)
6090+
v.Type = t
6091+
v.AddArg(n)
6092+
v0 := b.NewValue0(v.Pos, OpConst64, config.fe.TypeUInt64())
6093+
v0.AuxInt = log2(c)
6094+
v.AddArg(v0)
6095+
return true
6096+
}
6097+
// match: (Mul8 <t> n (Const8 [c]))
6098+
// cond: t.IsSigned() && isPowerOfTwo(-c)
6099+
// result: (Neg8 (Lsh8x64 <t> n (Const64 <config.fe.TypeUInt64()> [log2(-c)])))
6100+
for {
6101+
t := v.Type
6102+
n := v.Args[0]
6103+
v_1 := v.Args[1]
6104+
if v_1.Op != OpConst8 {
6105+
break
6106+
}
6107+
c := v_1.AuxInt
6108+
if !(t.IsSigned() && isPowerOfTwo(-c)) {
6109+
break
6110+
}
6111+
v.reset(OpNeg8)
6112+
v0 := b.NewValue0(v.Pos, OpLsh8x64, t)
6113+
v0.AddArg(n)
6114+
v1 := b.NewValue0(v.Pos, OpConst64, config.fe.TypeUInt64())
6115+
v1.AuxInt = log2(-c)
6116+
v0.AddArg(v1)
6117+
v.AddArg(v0)
6118+
return true
6119+
}
59406120
// match: (Mul8 x (Const8 <t> [c]))
59416121
// cond: x.Op != OpConst8
59426122
// result: (Mul8 (Const8 <t> [c]) x)

0 commit comments

Comments
 (0)