aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Munday <munday@ca.ibm.com>2017-02-28 14:28:28 -0500
committerMichael Munday <munday@ca.ibm.com>2017-03-02 04:25:56 +0000
commit865536b1977d57d398e3bffaba9f205f1172a262 (patch)
treefe6c561bd246c2e5bb2ad9efe1f20f637da9777a
parentbae53daa72bf2734acbb648b783752fbd00e357c (diff)
downloadgo-865536b1977d57d398e3bffaba9f205f1172a262.tar.gz
go-865536b1977d57d398e3bffaba9f205f1172a262.zip
[release-branch.go1.8] cmd/compile: remove unnecessary type conversions on s390x
Some rules insert MOVDreg ops to ensure that type changes are kept. If there is no type change (or the input is constant) then the MOVDreg can be omitted, allowing further optimization. Reduces the size of the .text section in the asm tool by ~33KB. For #19227. Change-Id: I0f7b40d8dbcda73bca96eb6d2bf13f9ffa88f4b6 Reviewed-on: https://go-review.googlesource.com/37535 Run-TryBot: Michael Munday <munday@ca.ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-rw-r--r--src/cmd/compile/internal/ssa/gen/S390X.rules10
-rw-r--r--src/cmd/compile/internal/ssa/rewriteS390X.go61
2 files changed, 70 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules
index c26515c569..4ba4ddb11c 100644
--- a/src/cmd/compile/internal/ssa/gen/S390X.rules
+++ b/src/cmd/compile/internal/ssa/gen/S390X.rules
@@ -448,7 +448,15 @@
// ***************************
// TODO: Should the optimizations be a separate pass?
-// if a register move has only 1 use, just use the same register without emitting instruction
+// Fold unnecessary type conversions.
+(MOVDreg <t> x) && t.Compare(x.Type) == CMPeq -> x
+(MOVDnop <t> x) && t.Compare(x.Type) == CMPeq -> x
+
+// Propagate constants through type conversions.
+(MOVDreg (MOVDconst [c])) -> (MOVDconst [c])
+(MOVDnop (MOVDconst [c])) -> (MOVDconst [c])
+
+// If a register move has only 1 use, just use the same register without emitting instruction.
// MOVDnop doesn't emit instruction, only for ensuring the type.
(MOVDreg x) && x.Uses == 1 -> (MOVDnop x)
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index 0425ced330..ae86541a03 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -524,6 +524,8 @@ func rewriteValueS390X(v *Value, config *Config) bool {
return rewriteValueS390X_OpS390XMOVDload(v, config)
case OpS390XMOVDloadidx:
return rewriteValueS390X_OpS390XMOVDloadidx(v, config)
+ case OpS390XMOVDnop:
+ return rewriteValueS390X_OpS390XMOVDnop(v, config)
case OpS390XMOVDreg:
return rewriteValueS390X_OpS390XMOVDreg(v, config)
case OpS390XMOVDstore:
@@ -10195,9 +10197,68 @@ func rewriteValueS390X_OpS390XMOVDloadidx(v *Value, config *Config) bool {
}
return false
}
+func rewriteValueS390X_OpS390XMOVDnop(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (MOVDnop <t> x)
+ // cond: t.Compare(x.Type) == CMPeq
+ // result: x
+ for {
+ t := v.Type
+ x := v.Args[0]
+ if !(t.Compare(x.Type) == CMPeq) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVDnop (MOVDconst [c]))
+ // cond:
+ // result: (MOVDconst [c])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpS390XMOVDconst)
+ v.AuxInt = c
+ return true
+ }
+ return false
+}
func rewriteValueS390X_OpS390XMOVDreg(v *Value, config *Config) bool {
b := v.Block
_ = b
+ // match: (MOVDreg <t> x)
+ // cond: t.Compare(x.Type) == CMPeq
+ // result: x
+ for {
+ t := v.Type
+ x := v.Args[0]
+ if !(t.Compare(x.Type) == CMPeq) {
+ break
+ }
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ // match: (MOVDreg (MOVDconst [c]))
+ // cond:
+ // result: (MOVDconst [c])
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpS390XMOVDconst {
+ break
+ }
+ c := v_0.AuxInt
+ v.reset(OpS390XMOVDconst)
+ v.AuxInt = c
+ return true
+ }
// match: (MOVDreg x)
// cond: x.Uses == 1
// result: (MOVDnop x)