From c87528d7761e3f133fe238937019a18bf7cf0d3c Mon Sep 17 00:00:00 2001 From: David Chase Date: Thu, 15 Sep 2016 15:14:32 -0700 Subject: [PATCH] cmd/compile: elide unnecessary sign/zeroExt, PPC64 Bias {Eq,Neq}{8,16} to prefer the extension likely to match their operand's load (if loaded), and elide sign and zero extending MOV{B,W}, MOV{B,W}Z when their operands are already appropriately extended. Change-Id: Ic01b9cab55e170f68fc2369688b50ce78a818608 Reviewed-on: https://go-review.googlesource.com/29236 Run-TryBot: David Chase TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/cmd/compile/internal/ssa/gen/PPC64.rules | 12 ++ src/cmd/compile/internal/ssa/rewritePPC64.go | 160 +++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules index 3f379129bd..c1be4c7953 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules @@ -196,6 +196,9 @@ // Lowering comparisons (EqB x y) -> (ANDconst [1] (EQV x y)) +// Sign extension dependence on operand sign sets up for sign/zero-extension elision later +(Eq8 x y) && isSigned(x.Type) && isSigned(y.Type) -> (Equal (CMPW (SignExt8to32 x) (SignExt8to32 y))) +(Eq16 x y) && isSigned(x.Type) && isSigned(y.Type) -> (Equal (CMPW (SignExt16to32 x) (SignExt16to32 y))) (Eq8 x y) -> (Equal (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y))) (Eq16 x y) -> (Equal (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y))) (Eq32 x y) -> (Equal (CMPW x y)) @@ -205,6 +208,9 @@ (EqPtr x y) -> (Equal (CMP x y)) (NeqB x y) -> (XOR x y) +// Like Eq8 and Eq16, prefer sign extension likely to enable later elision. +(Neq8 x y) && isSigned(x.Type) && isSigned(y.Type) -> (NotEqual (CMPW (SignExt8to32 x) (SignExt8to32 y))) +(Neq16 x y) && isSigned(x.Type) && isSigned(y.Type) -> (NotEqual (CMPW (SignExt16to32 x) (SignExt16to32 y))) (Neq8 x y) -> (NotEqual (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y))) (Neq16 x y) -> (NotEqual (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y))) (Neq32 x y) -> (NotEqual (CMPW x y)) @@ -620,3 +626,9 @@ (Trunc64to16 x) -> (MOVHreg x) (Trunc64to32 x) -> (MOVWreg x) +// 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) +(MOVBZreg x:(MOVBZload _ _)) -> x +(MOVBreg x:(MOVBload _ _)) -> x +(MOVHZreg x:(MOVHZload _ _)) -> x +(MOVHreg x:(MOVHload _ _)) -> x diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index 35441c9125..1a0a0d62ed 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -368,8 +368,12 @@ func rewriteValuePPC64(v *Value, config *Config) bool { return rewriteValuePPC64_OpPPC64LessThan(v, config) case OpPPC64MOVBZload: return rewriteValuePPC64_OpPPC64MOVBZload(v, config) + case OpPPC64MOVBZreg: + return rewriteValuePPC64_OpPPC64MOVBZreg(v, config) case OpPPC64MOVBload: return rewriteValuePPC64_OpPPC64MOVBload(v, config) + case OpPPC64MOVBreg: + return rewriteValuePPC64_OpPPC64MOVBreg(v, config) case OpPPC64MOVBstore: return rewriteValuePPC64_OpPPC64MOVBstore(v, config) case OpPPC64MOVBstorezero: @@ -382,8 +386,12 @@ func rewriteValuePPC64(v *Value, config *Config) bool { return rewriteValuePPC64_OpPPC64MOVDstorezero(v, config) case OpPPC64MOVHZload: return rewriteValuePPC64_OpPPC64MOVHZload(v, config) + case OpPPC64MOVHZreg: + return rewriteValuePPC64_OpPPC64MOVHZreg(v, config) case OpPPC64MOVHload: return rewriteValuePPC64_OpPPC64MOVHload(v, config) + case OpPPC64MOVHreg: + return rewriteValuePPC64_OpPPC64MOVHreg(v, config) case OpPPC64MOVHstore: return rewriteValuePPC64_OpPPC64MOVHstore(v, config) case OpPPC64MOVHstorezero: @@ -1296,6 +1304,26 @@ func rewriteValuePPC64_OpEq16(v *Value, config *Config) bool { b := v.Block _ = b // match: (Eq16 x y) + // cond: isSigned(x.Type) && isSigned(y.Type) + // result: (Equal (CMPW (SignExt16to32 x) (SignExt16to32 y))) + for { + x := v.Args[0] + y := v.Args[1] + if !(isSigned(x.Type) && isSigned(y.Type)) { + break + } + v.reset(OpPPC64Equal) + v0 := b.NewValue0(v.Line, OpPPC64CMPW, TypeFlags) + v1 := b.NewValue0(v.Line, OpSignExt16to32, config.fe.TypeInt32()) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Line, OpSignExt16to32, config.fe.TypeInt32()) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + return true + } + // match: (Eq16 x y) // cond: // result: (Equal (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y))) for { @@ -1385,6 +1413,26 @@ func rewriteValuePPC64_OpEq8(v *Value, config *Config) bool { b := v.Block _ = b // match: (Eq8 x y) + // cond: isSigned(x.Type) && isSigned(y.Type) + // result: (Equal (CMPW (SignExt8to32 x) (SignExt8to32 y))) + for { + x := v.Args[0] + y := v.Args[1] + if !(isSigned(x.Type) && isSigned(y.Type)) { + break + } + v.reset(OpPPC64Equal) + v0 := b.NewValue0(v.Line, OpPPC64CMPW, TypeFlags) + v1 := b.NewValue0(v.Line, OpSignExt8to32, config.fe.TypeInt32()) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Line, OpSignExt8to32, config.fe.TypeInt32()) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + return true + } + // match: (Eq8 x y) // cond: // result: (Equal (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y))) for { @@ -3626,6 +3674,26 @@ func rewriteValuePPC64_OpNeq16(v *Value, config *Config) bool { b := v.Block _ = b // match: (Neq16 x y) + // cond: isSigned(x.Type) && isSigned(y.Type) + // result: (NotEqual (CMPW (SignExt16to32 x) (SignExt16to32 y))) + for { + x := v.Args[0] + y := v.Args[1] + if !(isSigned(x.Type) && isSigned(y.Type)) { + break + } + v.reset(OpPPC64NotEqual) + v0 := b.NewValue0(v.Line, OpPPC64CMPW, TypeFlags) + v1 := b.NewValue0(v.Line, OpSignExt16to32, config.fe.TypeInt32()) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Line, OpSignExt16to32, config.fe.TypeInt32()) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + return true + } + // match: (Neq16 x y) // cond: // result: (NotEqual (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y))) for { @@ -3715,6 +3783,26 @@ func rewriteValuePPC64_OpNeq8(v *Value, config *Config) bool { b := v.Block _ = b // match: (Neq8 x y) + // cond: isSigned(x.Type) && isSigned(y.Type) + // result: (NotEqual (CMPW (SignExt8to32 x) (SignExt8to32 y))) + for { + x := v.Args[0] + y := v.Args[1] + if !(isSigned(x.Type) && isSigned(y.Type)) { + break + } + v.reset(OpPPC64NotEqual) + v0 := b.NewValue0(v.Line, OpPPC64CMPW, TypeFlags) + v1 := b.NewValue0(v.Line, OpSignExt8to32, config.fe.TypeInt32()) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Line, OpSignExt8to32, config.fe.TypeInt32()) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + return true + } + // match: (Neq8 x y) // cond: // result: (NotEqual (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y))) for { @@ -4676,6 +4764,24 @@ func rewriteValuePPC64_OpPPC64MOVBZload(v *Value, config *Config) bool { } return false } +func rewriteValuePPC64_OpPPC64MOVBZreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVBZreg x:(MOVBZload _ _)) + // cond: + // result: x + for { + x := v.Args[0] + if x.Op != OpPPC64MOVBZload { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64MOVBload(v *Value, config *Config) bool { b := v.Block _ = b @@ -4728,6 +4834,24 @@ func rewriteValuePPC64_OpPPC64MOVBload(v *Value, config *Config) bool { } return false } +func rewriteValuePPC64_OpPPC64MOVBreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVBreg x:(MOVBload _ _)) + // cond: + // result: x + for { + x := v.Args[0] + if x.Op != OpPPC64MOVBload { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64MOVBstore(v *Value, config *Config) bool { b := v.Block _ = b @@ -5046,6 +5170,24 @@ func rewriteValuePPC64_OpPPC64MOVHZload(v *Value, config *Config) bool { } return false } +func rewriteValuePPC64_OpPPC64MOVHZreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVHZreg x:(MOVHZload _ _)) + // cond: + // result: x + for { + x := v.Args[0] + if x.Op != OpPPC64MOVHZload { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64MOVHload(v *Value, config *Config) bool { b := v.Block _ = b @@ -5098,6 +5240,24 @@ func rewriteValuePPC64_OpPPC64MOVHload(v *Value, config *Config) bool { } return false } +func rewriteValuePPC64_OpPPC64MOVHreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVHreg x:(MOVHload _ _)) + // cond: + // result: x + for { + x := v.Args[0] + if x.Op != OpPPC64MOVHload { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64MOVHstore(v *Value, config *Config) bool { b := v.Block _ = b