aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/magic.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2020-04-28 19:28:43 -0700
committerKeith Randall <khr@golang.org>2020-04-29 16:45:32 +0000
commit3d34c77829e8ea79136e6f1c3b86abdd196ba8c5 (patch)
treef113f263192f2fc30903c036f0026dbd6f111b99 /src/cmd/compile/internal/ssa/magic.go
parent56933fb83852837f169cb35a23815f23c799da87 (diff)
downloadgo-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.go42
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) }