]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: simplify MOVWreg on ARM
authorCherry Zhang <cherryyz@google.com>
Fri, 15 Jul 2016 18:07:15 +0000 (14:07 -0400)
committerCherry Zhang <cherryyz@google.com>
Thu, 21 Jul 2016 16:46:58 +0000 (16:46 +0000)
For register-register move, if there is only one use, allocate it in
the same register so we don't need to emit an instruction.

Updates #15365.

Change-Id: Iad41843854a506c521d577ad93fcbe73e8de8065
Reviewed-on: https://go-review.googlesource.com/25059
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/ssa/gen/ARM.rules
src/cmd/compile/internal/ssa/gen/ARMOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteARM.go

index 99a264a1679f2ea927cbad974182ebd462419aeb..bdb3c36cf409822dfc4ecbe724de7bd832d35315 100644 (file)
@@ -194,6 +194,11 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.From.Reg = x
                p.To.Type = obj.TYPE_REG
                p.To.Reg = y
+       case ssa.OpARMMOVWnop:
+               if gc.SSARegNum(v) != gc.SSARegNum(v.Args[0]) {
+                       v.Fatalf("input[0] and output not in same register %s", v.LongString())
+               }
+               // nothing to do
        case ssa.OpLoadReg:
                if v.Type.IsFlags() {
                        v.Unimplementedf("load flags not implemented: %v", v.LongString())
@@ -636,7 +641,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                ssa.OpARMMOVHreg,
                ssa.OpARMMOVHUreg:
                a := v.Args[0]
-               for a.Op == ssa.OpCopy || a.Op == ssa.OpARMMOVWreg {
+               for a.Op == ssa.OpCopy || a.Op == ssa.OpARMMOVWreg || a.Op == ssa.OpARMMOVWnop {
                        a = a.Args[0]
                }
                if a.Op == ssa.OpLoadReg {
index 7e6577692d9756dd0c5d10811fc0b066dd431863..17d151d824327d520b49f85d7baf8fa0e4906591 100644 (file)
 (MOVHstore [off] {sym} ptr (MOVHreg x) mem) -> (MOVHstore [off] {sym} ptr x mem)
 (MOVHstore [off] {sym} ptr (MOVHUreg x) mem) -> (MOVHstore [off] {sym} ptr x mem)
 
+// if a register move has only 1 use, just use the same register without emitting instruction
+// MOVWnop doesn't emit instruction, only for ensuring the type.
+(MOVWreg x) && x.Uses == 1 -> (MOVWnop x)
+
 // mul by constant
 (MUL x (MOVWconst [c])) && int32(c) == -1 -> (RSBconst [0] x)
 (MUL _ (MOVWconst [0])) -> (MOVWconst [0])
index 9f351078d870319eeded68c4498832dd863e3a13..85e1e2f941be4dcdc79bc689292554997965c349 100644 (file)
@@ -344,6 +344,8 @@ func init() {
                {name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
                {name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0
 
+               {name: "MOVWnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
+
                {name: "MOVWF", argLength: 1, reg: gpfp, asm: "MOVWF"},  // int32 -> float32
                {name: "MOVWD", argLength: 1, reg: gpfp, asm: "MOVWD"},  // int32 -> float64
                {name: "MOVWUF", argLength: 1, reg: gpfp, asm: "MOVWF"}, // uint32 -> float32, set U bit in the instruction
index 23cdab6a85fe823cec866181580a45337b7d325f..a665c433b1c08358c21dcce195d15fc9eeb3fdc1 100644 (file)
@@ -729,6 +729,7 @@ const (
        OpARMMOVHreg
        OpARMMOVHUreg
        OpARMMOVWreg
+       OpARMMOVWnop
        OpARMMOVWF
        OpARMMOVWD
        OpARMMOVWUF
@@ -9328,6 +9329,19 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:         "MOVWnop",
+               argLen:       1,
+               resultInArg0: true,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+                       outputs: []outputInfo{
+                               {0, 5119}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12
+                       },
+               },
+       },
        {
                name:   "MOVWF",
                argLen: 1,
index 7e2435dc2f60d81d62f75ce83c9d63c602317c14..c391ffa43623c30e56345957685d3842322d5f79 100644 (file)
@@ -8804,6 +8804,18 @@ func rewriteValueARM_OpARMMOVWloadshiftRL(v *Value, config *Config) bool {
 func rewriteValueARM_OpARMMOVWreg(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (MOVWreg x)
+       // cond: x.Uses == 1
+       // result: (MOVWnop x)
+       for {
+               x := v.Args[0]
+               if !(x.Uses == 1) {
+                       break
+               }
+               v.reset(OpARMMOVWnop)
+               v.AddArg(x)
+               return true
+       }
        // match: (MOVWreg (MOVWconst [c]))
        // cond:
        // result: (MOVWconst [c])