From d8181d5d75821ad5b78ea7f4163dd86ac29f740a Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Fri, 15 Jul 2016 14:07:15 -0400 Subject: [PATCH] [dev.ssa] cmd/compile: simplify MOVWreg on ARM 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 TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- src/cmd/compile/internal/arm/ssa.go | 7 ++++++- src/cmd/compile/internal/ssa/gen/ARM.rules | 4 ++++ src/cmd/compile/internal/ssa/gen/ARMOps.go | 2 ++ src/cmd/compile/internal/ssa/opGen.go | 14 ++++++++++++++ src/cmd/compile/internal/ssa/rewriteARM.go | 12 ++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go index 99a264a167..bdb3c36cf4 100644 --- a/src/cmd/compile/internal/arm/ssa.go +++ b/src/cmd/compile/internal/arm/ssa.go @@ -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 { diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules index 7e6577692d..17d151d824 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM.rules @@ -520,6 +520,10 @@ (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]) diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go index 9f351078d8..85e1e2f941 100644 --- a/src/cmd/compile/internal/ssa/gen/ARMOps.go +++ b/src/cmd/compile/internal/ssa/gen/ARMOps.go @@ -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 diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 23cdab6a85..a665c433b1 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -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, diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go index 7e2435dc2f..c391ffa436 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM.go +++ b/src/cmd/compile/internal/ssa/rewriteARM.go @@ -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]) -- 2.48.1