mirror of https://github.com/golang/go.git
cmd/compile: better implementation of Slicemask
Use (-x)>>63 instead of ((x-1)>>63)^-1 to get a mask that is 0 when x is 0 and all ones when x is positive. Saves one instruction when slicing. Change-Id: Ib46d53d3aac6530ac481fa2f265a6eadf3df0567 Reviewed-on: https://go-review.googlesource.com/35641 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
0358367576
commit
3d5eb4a6be
|
|
@ -102,7 +102,7 @@
|
|||
|
||||
(Signmask x) -> (SARLconst x [31])
|
||||
(Zeromask <t> x) -> (XORLconst [-1] (SBBLcarrymask <t> (CMPLconst x [1])))
|
||||
(Slicemask <t> x) -> (XORLconst [-1] (SARLconst <t> (SUBLconst <t> x [1]) [31]))
|
||||
(Slicemask <t> x) -> (SARLconst (NEGL <t> x) [31])
|
||||
|
||||
// Lowering truncation
|
||||
// Because we ignore high parts of registers, truncates are just copies.
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@
|
|||
(ZeroExt16to64 x) -> (MOVWQZX x)
|
||||
(ZeroExt32to64 x) -> (MOVLQZX x)
|
||||
|
||||
(Slicemask <t> x) -> (XORQconst [-1] (SARQconst <t> (SUBQconst <t> x [1]) [63]))
|
||||
(Slicemask <t> x) -> (SARQconst (NEGQ <t> x) [63])
|
||||
|
||||
// Lowering truncation
|
||||
// Because we ignore high parts of registers, truncates are just copies.
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@
|
|||
|
||||
(Signmask x) -> (SRAconst x [31])
|
||||
(Zeromask x) -> (SRAconst (RSBshiftRL <config.fe.TypeInt32()> x x [1]) [31]) // sign bit of uint32(x)>>1 - x
|
||||
(Slicemask <t> x) -> (MVN (SRAconst <t> (SUBconst <t> x [1]) [31]))
|
||||
(Slicemask <t> x) -> (SRAconst (RSBconst <t> [0] x) [31])
|
||||
|
||||
// float <-> int conversion
|
||||
(Cvt32to32F x) -> (MOVWF x)
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@
|
|||
(ConstNil) -> (MOVDconst [0])
|
||||
(ConstBool [b]) -> (MOVDconst [b])
|
||||
|
||||
(Slicemask <t> x) -> (MVN (SRAconst <t> (SUBconst <t> x [1]) [63]))
|
||||
(Slicemask <t> x) -> (SRAconst (NEG <t> x) [63])
|
||||
|
||||
// truncations
|
||||
// Because we ignore high parts of registers, truncates are just copies.
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@
|
|||
|
||||
(Signmask x) -> (SRAconst x [31])
|
||||
(Zeromask x) -> (NEG (SGTU x (MOVWconst [0])))
|
||||
(Slicemask x) -> (NEG (SGT x (MOVWconst [0])))
|
||||
(Slicemask <t> x) -> (SRAconst (NEG <t> x) [31])
|
||||
|
||||
// float <-> int conversion
|
||||
(Cvt32to32F x) -> (MOVWF x)
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@
|
|||
(ConstNil) -> (MOVVconst [0])
|
||||
(ConstBool [b]) -> (MOVVconst [b])
|
||||
|
||||
(Slicemask <t> x) -> (NORconst [0] (SRAVconst <t> (SUBVconst <t> x [1]) [63]))
|
||||
(Slicemask <t> x) -> (SRAVconst (NEGV <t> x) [63])
|
||||
|
||||
// truncations
|
||||
// Because we ignore high parts of registers, truncates are just copies.
|
||||
|
|
|
|||
|
|
@ -790,7 +790,7 @@
|
|||
(Trunc64to16 x) -> (MOVHreg x)
|
||||
(Trunc64to32 x) -> (MOVWreg x)
|
||||
|
||||
(Slicemask <t> x) -> (XORconst [-1] (SRADconst <t> (ADDconst <t> x [-1]) [63]))
|
||||
(Slicemask <t> x) -> (SRADconst (NEG <t> x) [63])
|
||||
|
||||
// Note that MOV??reg returns a 64-bit int, x is not necessarily that wide
|
||||
// This may interact with other patterns in the future. (Compare with arm64)
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@
|
|||
(ZeroExt16to64 x) -> (MOVHZreg x)
|
||||
(ZeroExt32to64 x) -> (MOVWZreg x)
|
||||
|
||||
(Slicemask <t> x) -> (XOR (MOVDconst [-1]) (SRADconst <t> (SUBconst <t> x [1]) [63]))
|
||||
(Slicemask <t> x) -> (SRADconst (NEG <t> x) [63])
|
||||
|
||||
// Lowering truncation
|
||||
// Because we ignore high parts of registers, truncates are just copies.
|
||||
|
|
|
|||
|
|
@ -12932,18 +12932,14 @@ func rewriteValue386_OpSlicemask(v *Value, config *Config) bool {
|
|||
_ = b
|
||||
// match: (Slicemask <t> x)
|
||||
// cond:
|
||||
// result: (XORLconst [-1] (SARLconst <t> (SUBLconst <t> x [1]) [31]))
|
||||
// result: (SARLconst (NEGL <t> x) [31])
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
v.reset(Op386XORLconst)
|
||||
v.AuxInt = -1
|
||||
v0 := b.NewValue0(v.Pos, Op386SARLconst, t)
|
||||
v0.AuxInt = 31
|
||||
v1 := b.NewValue0(v.Pos, Op386SUBLconst, t)
|
||||
v1.AuxInt = 1
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
v.reset(Op386SARLconst)
|
||||
v.AuxInt = 31
|
||||
v0 := b.NewValue0(v.Pos, Op386NEGL, t)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20168,18 +20168,14 @@ func rewriteValueAMD64_OpSlicemask(v *Value, config *Config) bool {
|
|||
_ = b
|
||||
// match: (Slicemask <t> x)
|
||||
// cond:
|
||||
// result: (XORQconst [-1] (SARQconst <t> (SUBQconst <t> x [1]) [63]))
|
||||
// result: (SARQconst (NEGQ <t> x) [63])
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
v.reset(OpAMD64XORQconst)
|
||||
v.AuxInt = -1
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64SARQconst, t)
|
||||
v0.AuxInt = 63
|
||||
v1 := b.NewValue0(v.Pos, OpAMD64SUBQconst, t)
|
||||
v1.AuxInt = 1
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
v.reset(OpAMD64SARQconst)
|
||||
v.AuxInt = 63
|
||||
v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16598,17 +16598,15 @@ func rewriteValueARM_OpSlicemask(v *Value, config *Config) bool {
|
|||
_ = b
|
||||
// match: (Slicemask <t> x)
|
||||
// cond:
|
||||
// result: (MVN (SRAconst <t> (SUBconst <t> x [1]) [31]))
|
||||
// result: (SRAconst (RSBconst <t> [0] x) [31])
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
v.reset(OpARMMVN)
|
||||
v0 := b.NewValue0(v.Pos, OpARMSRAconst, t)
|
||||
v0.AuxInt = 31
|
||||
v1 := b.NewValue0(v.Pos, OpARMSUBconst, t)
|
||||
v1.AuxInt = 1
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
v.reset(OpARMSRAconst)
|
||||
v.AuxInt = 31
|
||||
v0 := b.NewValue0(v.Pos, OpARMRSBconst, t)
|
||||
v0.AuxInt = 0
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14480,17 +14480,14 @@ func rewriteValueARM64_OpSlicemask(v *Value, config *Config) bool {
|
|||
_ = b
|
||||
// match: (Slicemask <t> x)
|
||||
// cond:
|
||||
// result: (MVN (SRAconst <t> (SUBconst <t> x [1]) [63]))
|
||||
// result: (SRAconst (NEG <t> x) [63])
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
v.reset(OpARM64MVN)
|
||||
v0 := b.NewValue0(v.Pos, OpARM64SRAconst, t)
|
||||
v0.AuxInt = 63
|
||||
v1 := b.NewValue0(v.Pos, OpARM64SUBconst, t)
|
||||
v1.AuxInt = 1
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
v.reset(OpARM64SRAconst)
|
||||
v.AuxInt = 63
|
||||
v0 := b.NewValue0(v.Pos, OpARM64NEG, t)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8304,17 +8304,16 @@ func rewriteValueMIPS_OpSignmask(v *Value, config *Config) bool {
|
|||
func rewriteValueMIPS_OpSlicemask(v *Value, config *Config) bool {
|
||||
b := v.Block
|
||||
_ = b
|
||||
// match: (Slicemask x)
|
||||
// match: (Slicemask <t> x)
|
||||
// cond:
|
||||
// result: (NEG (SGT x (MOVWconst [0])))
|
||||
// result: (SRAconst (NEG <t> x) [31])
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
v.reset(OpMIPSNEG)
|
||||
v0 := b.NewValue0(v.Pos, OpMIPSSGT, config.fe.TypeBool())
|
||||
v.reset(OpMIPSSRAconst)
|
||||
v.AuxInt = 31
|
||||
v0 := b.NewValue0(v.Pos, OpMIPSNEG, t)
|
||||
v0.AddArg(x)
|
||||
v1 := b.NewValue0(v.Pos, OpMIPSMOVWconst, config.fe.TypeUInt32())
|
||||
v1.AuxInt = 0
|
||||
v0.AddArg(v1)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8815,18 +8815,14 @@ func rewriteValueMIPS64_OpSlicemask(v *Value, config *Config) bool {
|
|||
_ = b
|
||||
// match: (Slicemask <t> x)
|
||||
// cond:
|
||||
// result: (NORconst [0] (SRAVconst <t> (SUBVconst <t> x [1]) [63]))
|
||||
// result: (SRAVconst (NEGV <t> x) [63])
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
v.reset(OpMIPS64NORconst)
|
||||
v.AuxInt = 0
|
||||
v0 := b.NewValue0(v.Pos, OpMIPS64SRAVconst, t)
|
||||
v0.AuxInt = 63
|
||||
v1 := b.NewValue0(v.Pos, OpMIPS64SUBVconst, t)
|
||||
v1.AuxInt = 1
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
v.reset(OpMIPS64SRAVconst)
|
||||
v.AuxInt = 63
|
||||
v0 := b.NewValue0(v.Pos, OpMIPS64NEGV, t)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9084,18 +9084,14 @@ func rewriteValuePPC64_OpSlicemask(v *Value, config *Config) bool {
|
|||
_ = b
|
||||
// match: (Slicemask <t> x)
|
||||
// cond:
|
||||
// result: (XORconst [-1] (SRADconst <t> (ADDconst <t> x [-1]) [63]))
|
||||
// result: (SRADconst (NEG <t> x) [63])
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
v.reset(OpPPC64XORconst)
|
||||
v.AuxInt = -1
|
||||
v0 := b.NewValue0(v.Pos, OpPPC64SRADconst, t)
|
||||
v0.AuxInt = 63
|
||||
v1 := b.NewValue0(v.Pos, OpPPC64ADDconst, t)
|
||||
v1.AuxInt = -1
|
||||
v1.AddArg(x)
|
||||
v0.AddArg(v1)
|
||||
v.reset(OpPPC64SRADconst)
|
||||
v.AuxInt = 63
|
||||
v0 := b.NewValue0(v.Pos, OpPPC64NEG, t)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17290,21 +17290,15 @@ func rewriteValueS390X_OpSlicemask(v *Value, config *Config) bool {
|
|||
_ = b
|
||||
// match: (Slicemask <t> x)
|
||||
// cond:
|
||||
// result: (XOR (MOVDconst [-1]) (SRADconst <t> (SUBconst <t> x [1]) [63]))
|
||||
// result: (SRADconst (NEG <t> x) [63])
|
||||
for {
|
||||
t := v.Type
|
||||
x := v.Args[0]
|
||||
v.reset(OpS390XXOR)
|
||||
v0 := b.NewValue0(v.Pos, OpS390XMOVDconst, config.fe.TypeUInt64())
|
||||
v0.AuxInt = -1
|
||||
v.reset(OpS390XSRADconst)
|
||||
v.AuxInt = 63
|
||||
v0 := b.NewValue0(v.Pos, OpS390XNEG, t)
|
||||
v0.AddArg(x)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, OpS390XSRADconst, t)
|
||||
v1.AuxInt = 63
|
||||
v2 := b.NewValue0(v.Pos, OpS390XSUBconst, t)
|
||||
v2.AuxInt = 1
|
||||
v2.AddArg(x)
|
||||
v1.AddArg(v2)
|
||||
v.AddArg(v1)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue