diff options
author | Keith Randall <khr@golang.org> | 2020-04-28 19:28:43 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2020-04-29 16:45:32 +0000 |
commit | 3d34c77829e8ea79136e6f1c3b86abdd196ba8c5 (patch) | |
tree | f113f263192f2fc30903c036f0026dbd6f111b99 /src/cmd/compile/internal/ssa/magic.go | |
parent | 56933fb83852837f169cb35a23815f23c799da87 (diff) | |
download | go-3d34c77829e8ea79136e6f1c3b86abdd196ba8c5.tar.gz go-3d34c77829e8ea79136e6f1c3b86abdd196ba8c5.zip |
cmd/compile: convert constant divide strength reduction rules to typed aux
Passes toolstash-check.
Change-Id: Ia5d11c099b8c6c0ed670960b2af808200e3b1ca1
Reviewed-on: https://go-review.googlesource.com/c/go/+/230739
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa/magic.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/magic.go | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/ssa/magic.go b/src/cmd/compile/internal/ssa/magic.go index 6e90d06ae0..93f8801bce 100644 --- a/src/cmd/compile/internal/ssa/magic.go +++ b/src/cmd/compile/internal/ssa/magic.go @@ -96,7 +96,7 @@ func umagicOK(n uint, c int64) bool { return d&(d-1) != 0 } -// umagicOKn reports whether we should strength reduce an n-bit divide by c. +// umagicOKn reports whether we should strength reduce an unsigned n-bit divide by c. // We can strength reduce when c != 0 and c is not a power of two. func umagicOK8(c int8) bool { return c&(c-1) != 0 } func umagicOK16(c int16) bool { return c&(c-1) != 0 } @@ -130,6 +130,11 @@ func umagic(n uint, c int64) umagicData { return umagicData{s: int64(s), m: m} } +func umagic8(c int8) umagicData { return umagic(8, int64(c)) } +func umagic16(c int16) umagicData { return umagic(16, int64(c)) } +func umagic32(c int32) umagicData { return umagic(32, int64(c)) } +func umagic64(c int64) umagicData { return umagic(64, c) } + // For signed division, we use a similar strategy. // First, we enforce a positive c. // x / c = -(x / (-c)) @@ -164,6 +169,12 @@ func smagicOK(n uint, c int64) bool { return c&(c-1) != 0 } +// smagicOKn reports whether we should strength reduce an signed n-bit divide by c. +func smagicOK8(c int8) bool { return smagicOK(8, int64(c)) } +func smagicOK16(c int16) bool { return smagicOK(16, int64(c)) } +func smagicOK32(c int32) bool { return smagicOK(32, int64(c)) } +func smagicOK64(c int64) bool { return smagicOK(64, c) } + type smagicData struct { s int64 // ⎡log2(c)⎤-1 m uint64 // ⎡2^(n+s)/c⎤ @@ -191,6 +202,11 @@ func smagic(n uint, c int64) smagicData { return smagicData{s: int64(s), m: m} } +func smagic8(c int8) smagicData { return smagic(8, int64(c)) } +func smagic16(c int16) smagicData { return smagic(16, int64(c)) } +func smagic32(c int32) smagicData { return smagic(32, int64(c)) } +func smagic64(c int64) smagicData { return smagic(64, c) } + // Divisibility x%c == 0 can be checked more efficiently than directly computing // the modulus x%c and comparing against 0. // @@ -249,7 +265,7 @@ func smagic(n uint, c int64) smagicData { // // Where d0*2^k was replaced by c on the right hand side. -// uivisibleOK reports whether we should strength reduce a n-bit dividisibilty check by c. +// udivisibleOK reports whether we should strength reduce an unsigned n-bit divisibilty check by c. func udivisibleOK(n uint, c int64) bool { // Convert from ConstX auxint values to the real uint64 constant they represent. d := uint64(c) << (64 - n) >> (64 - n) @@ -259,6 +275,11 @@ func udivisibleOK(n uint, c int64) bool { return d&(d-1) != 0 } +func udivisibleOK8(c int8) bool { return udivisibleOK(8, int64(c)) } +func udivisibleOK16(c int16) bool { return udivisibleOK(16, int64(c)) } +func udivisibleOK32(c int32) bool { return udivisibleOK(32, int64(c)) } +func udivisibleOK64(c int64) bool { return udivisibleOK(64, c) } + type udivisibleData struct { k int64 // trailingZeros(c) m uint64 // m * (c>>k) mod 2^n == 1 multiplicative inverse of odd portion modulo 2^n @@ -293,6 +314,11 @@ func udivisible(n uint, c int64) udivisibleData { } } +func udivisible8(c int8) udivisibleData { return udivisible(8, int64(c)) } +func udivisible16(c int16) udivisibleData { return udivisible(16, int64(c)) } +func udivisible32(c int32) udivisibleData { return udivisible(32, int64(c)) } +func udivisible64(c int64) udivisibleData { return udivisible(64, c) } + // For signed integers, a similar method follows. // // Given c > 1 and odd, compute m such that (c * m) mod 2^n == 1 @@ -341,7 +367,7 @@ func udivisible(n uint, c int64) udivisibleData { // Note that the calculation is performed using unsigned integers. // Since a' can have n-1 bits, 2a' may have n bits and there is no risk of overflow. -// sdivisibleOK reports whether we should strength reduce a n-bit dividisibilty check by c. +// sdivisibleOK reports whether we should strength reduce a signed n-bit divisibilty check by c. func sdivisibleOK(n uint, c int64) bool { if c < 0 { // Doesn't work for negative c. @@ -352,6 +378,11 @@ func sdivisibleOK(n uint, c int64) bool { return c&(c-1) != 0 } +func sdivisibleOK8(c int8) bool { return sdivisibleOK(8, int64(c)) } +func sdivisibleOK16(c int16) bool { return sdivisibleOK(16, int64(c)) } +func sdivisibleOK32(c int32) bool { return sdivisibleOK(32, int64(c)) } +func sdivisibleOK64(c int64) bool { return sdivisibleOK(64, c) } + type sdivisibleData struct { k int64 // trailingZeros(c) m uint64 // m * (c>>k) mod 2^n == 1 multiplicative inverse of odd portion modulo 2^n @@ -386,3 +417,8 @@ func sdivisible(n uint, c int64) sdivisibleData { max: max, } } + +func sdivisible8(c int8) sdivisibleData { return sdivisible(8, int64(c)) } +func sdivisible16(c int16) sdivisibleData { return sdivisible(16, int64(c)) } +func sdivisible32(c int32) sdivisibleData { return sdivisible(32, int64(c)) } +func sdivisible64(c int64) sdivisibleData { return sdivisible(64, c) } |