]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove unnecessary type conversions on s390x
authorMichael Munday <munday@ca.ibm.com>
Tue, 7 Feb 2017 23:32:27 +0000 (18:32 -0500)
committerMichael Munday <munday@ca.ibm.com>
Wed, 8 Feb 2017 19:29:41 +0000 (19:29 +0000)
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.

Change-Id: I386883bb35b843c7b99a269cd6840dca77cf4371
Reviewed-on: https://go-review.googlesource.com/36547
Run-TryBot: Michael Munday <munday@ca.ibm.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/ssa/gen/S390X.rules
src/cmd/compile/internal/ssa/rewriteS390X.go

index d0a0be911b88caa450a597fd6ec30ee5054f1674..9907d5b28129f90cd7a97d3e7f653c8d86f22739 100644 (file)
 // ***************************
 // 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)
 
index af6b66219311881ed346412968b0d5fc1cbc0025..da6ff6b112cb7d54273998d5450b75d0b3ec49d2 100644 (file)
@@ -520,6 +520,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:
@@ -10257,9 +10259,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)