aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/rewrite.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/ssa/rewrite.go')
-rw-r--r--src/cmd/compile/internal/ssa/rewrite.go60
1 files changed, 24 insertions, 36 deletions
diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go
index b3e7d34779..727fd2402d 100644
--- a/src/cmd/compile/internal/ssa/rewrite.go
+++ b/src/cmd/compile/internal/ssa/rewrite.go
@@ -347,9 +347,10 @@ func nlz(x int64) int64 {
}
// ntz returns the number of trailing zeros.
-func ntz(x int64) int64 {
- return int64(bits.TrailingZeros64(uint64(x)))
-}
+func ntz(x int64) int64 { return int64(bits.TrailingZeros64(uint64(x))) }
+func ntz32(x int64) int64 { return int64(bits.TrailingZeros32(uint32(x))) }
+func ntz16(x int64) int64 { return int64(bits.TrailingZeros16(uint16(x))) }
+func ntz8(x int64) int64 { return int64(bits.TrailingZeros8(uint8(x))) }
func oneBit(x int64) bool {
return bits.OnesCount64(uint64(x)) == 1
@@ -990,7 +991,9 @@ func zeroUpper32Bits(x *Value, depth int) bool {
OpAMD64ORLload, OpAMD64XORLload, OpAMD64CVTTSD2SL,
OpAMD64ADDL, OpAMD64ADDLconst, OpAMD64SUBL, OpAMD64SUBLconst,
OpAMD64ANDL, OpAMD64ANDLconst, OpAMD64ORL, OpAMD64ORLconst,
- OpAMD64XORL, OpAMD64XORLconst, OpAMD64NEGL, OpAMD64NOTL:
+ OpAMD64XORL, OpAMD64XORLconst, OpAMD64NEGL, OpAMD64NOTL,
+ OpAMD64SHRL, OpAMD64SHRLconst, OpAMD64SARL, OpAMD64SARLconst,
+ OpAMD64SHLL, OpAMD64SHLLconst:
return true
case OpArg:
return x.Type.Width == 4
@@ -1248,42 +1251,27 @@ func read64(sym interface{}, off int64, byteorder binary.ByteOrder) uint64 {
return byteorder.Uint64(buf)
}
-// same reports whether x and y are the same value.
-// It checks to a maximum depth of d, so it may report
-// a false negative.
-func same(x, y *Value, depth int) bool {
- if x == y {
+// sequentialAddresses reports true if it can prove that x + n == y
+func sequentialAddresses(x, y *Value, n int64) bool {
+ if x.Op == Op386ADDL && y.Op == Op386LEAL1 && y.AuxInt == n && y.Aux == nil &&
+ (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
+ x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
return true
}
- if depth <= 0 {
- return false
- }
- if x.Op != y.Op || x.Aux != y.Aux || x.AuxInt != y.AuxInt {
- return false
- }
- if len(x.Args) != len(y.Args) {
- return false
+ if x.Op == Op386LEAL1 && y.Op == Op386LEAL1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
+ (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
+ x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
+ return true
}
- if opcodeTable[x.Op].commutative {
- // Check exchanged ordering first.
- for i, a := range x.Args {
- j := i
- if j < 2 {
- j ^= 1
- }
- b := y.Args[j]
- if !same(a, b, depth-1) {
- goto checkNormalOrder
- }
- }
+ if x.Op == OpAMD64ADDQ && y.Op == OpAMD64LEAQ1 && y.AuxInt == n && y.Aux == nil &&
+ (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
+ x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
return true
- checkNormalOrder:
}
- for i, a := range x.Args {
- b := y.Args[i]
- if !same(a, b, depth-1) {
- return false
- }
+ if x.Op == OpAMD64LEAQ1 && y.Op == OpAMD64LEAQ1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
+ (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
+ x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
+ return true
}
- return true
+ return false
}