]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't lower OpConvert
authorAustin Clements <austin@google.com>
Mon, 2 Apr 2018 20:08:09 +0000 (16:08 -0400)
committerAustin Clements <austin@google.com>
Fri, 20 Apr 2018 18:46:39 +0000 (18:46 +0000)
Currently, each architecture lowers OpConvert to an arch-specific
OpXXXconvert. This is silly because OpConvert means the same thing on
all architectures and is logically a no-op that exists only to keep
track of conversions to and from unsafe.Pointer. Furthermore, lowering
it makes it harder to recognize in other analyses, particularly
liveness analysis.

This CL eliminates the lowering of OpConvert, leaving it as the
generic op until code generation time.

The main complexity here is that we still need to register-allocate
OpConvert operations. Currently, each arch's lowered OpConvert
specifies all GP registers in its register mask. Ideally, OpConvert
wouldn't affect value homing at all, and we could just copy the home
of OpConvert's source, but this can potentially home an OpConvert in a
LocalSlot, which neither regalloc nor stackalloc expect. Rather than
try to disentangle this assumption from regalloc and stackalloc, we
continue to register-allocate OpConvert, but teach regalloc that
OpConvert can be allocated to any allocatable GP register.

For #24543.

Change-Id: I795a6aee5fd94d4444a7bafac3838a400c9f7bb6
Reviewed-on: https://go-review.googlesource.com/108496
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
38 files changed:
src/cmd/compile/internal/amd64/ssa.go
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/mips/ssa.go
src/cmd/compile/internal/mips64/ssa.go
src/cmd/compile/internal/ppc64/ssa.go
src/cmd/compile/internal/s390x/ssa.go
src/cmd/compile/internal/ssa/gen/386.rules
src/cmd/compile/internal/ssa/gen/386Ops.go
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/gen/AMD64Ops.go
src/cmd/compile/internal/ssa/gen/ARM.rules
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/gen/ARM64Ops.go
src/cmd/compile/internal/ssa/gen/ARMOps.go
src/cmd/compile/internal/ssa/gen/MIPS.rules
src/cmd/compile/internal/ssa/gen/MIPS64.rules
src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
src/cmd/compile/internal/ssa/gen/MIPSOps.go
src/cmd/compile/internal/ssa/gen/PPC64.rules
src/cmd/compile/internal/ssa/gen/PPC64Ops.go
src/cmd/compile/internal/ssa/gen/S390X.rules
src/cmd/compile/internal/ssa/gen/S390XOps.go
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/gen/main.go
src/cmd/compile/internal/ssa/lower.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/regalloc.go
src/cmd/compile/internal/ssa/rewrite386.go
src/cmd/compile/internal/ssa/rewriteAMD64.go
src/cmd/compile/internal/ssa/rewriteARM.go
src/cmd/compile/internal/ssa/rewriteARM64.go
src/cmd/compile/internal/ssa/rewriteMIPS.go
src/cmd/compile/internal/ssa/rewriteMIPS64.go
src/cmd/compile/internal/ssa/rewritePPC64.go
src/cmd/compile/internal/ssa/rewriteS390X.go
src/cmd/compile/internal/x86/ssa.go

index e7decb9eb6b96a4ae6161b97ca3438ac221242ae..527fb3a69b8c23ef543f5ae05e2d479a482db774 100644 (file)
@@ -846,10 +846,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Sym = gc.Duffcopy
                p.To.Offset = v.AuxInt
 
-       case ssa.OpAMD64MOVQconvert, ssa.OpAMD64MOVLconvert:
-               if v.Args[0].Reg() != v.Reg() {
-                       v.Fatalf("MOVXconvert should be a no-op")
-               }
        case ssa.OpCopy: // TODO: use MOVQreg for reg->reg copies instead of OpCopy?
                if v.Type.IsMemory() {
                        return
index 1c3b7eae11d5fd03942e8f1fa2c1175d14939c7f..4c8358f5957384ff104ad6aad97853650cdc3920 100644 (file)
@@ -121,7 +121,7 @@ func genregshift(s *gc.SSAGenState, as obj.As, r0, r1, r2, r int16, typ int64) *
 
 func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        switch v.Op {
-       case ssa.OpCopy, ssa.OpARMMOVWconvert, ssa.OpARMMOVWreg:
+       case ssa.OpCopy, ssa.OpARMMOVWreg:
                if v.Type.IsMemory() {
                        return
                }
index e194f9c40313784f5ea6cfa1fe498feb20343de4..ea3fe7a094294e2d6e3eb72f96fa77e8a6b52fe2 100644 (file)
@@ -94,7 +94,7 @@ func genshift(s *gc.SSAGenState, as obj.As, r0, r1, r int16, typ int64, n int64)
 
 func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        switch v.Op {
-       case ssa.OpCopy, ssa.OpARM64MOVDconvert, ssa.OpARM64MOVDreg:
+       case ssa.OpCopy, ssa.OpARM64MOVDreg:
                if v.Type.IsMemory() {
                        return
                }
index 7c030fa80a6f0dcf56d7be873eff5d70a336340a..eb20276675108cd72571a7c7ad3e248cbf1f0664 100644 (file)
@@ -4806,6 +4806,11 @@ func genssa(f *ssa.Func, pp *Progs) {
                                }
                        case ssa.OpPhi:
                                CheckLoweredPhi(v)
+                       case ssa.OpConvert:
+                               // nothing to do; no-op conversion for liveness
+                               if v.Args[0].Reg() != v.Reg() {
+                                       v.Fatalf("OpConvert should be a no-op: %s; %s", v.Args[0].LongString(), v.LongString())
+                               }
                        default:
                                // let the backend handle it
                                // Special case for first line in function; move it to the start.
index 0098d1ce2b55f8fb28a930cf95406569810002c8..7a81ce911ba4ed4754be0026f18e15c1c201bd6f 100644 (file)
@@ -76,7 +76,7 @@ func storeByType(t *types.Type, r int16) obj.As {
 
 func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        switch v.Op {
-       case ssa.OpCopy, ssa.OpMIPSMOVWconvert, ssa.OpMIPSMOVWreg:
+       case ssa.OpCopy, ssa.OpMIPSMOVWreg:
                t := v.Type
                if t.IsMemory() {
                        return
index d8645946de430dd75109894831aefae40783f5a6..33b3152e189f95ad282ac07d3c32e149ee00ba3d 100644 (file)
@@ -84,7 +84,7 @@ func storeByType(t *types.Type, r int16) obj.As {
 
 func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        switch v.Op {
-       case ssa.OpCopy, ssa.OpMIPS64MOVVconvert, ssa.OpMIPS64MOVVreg:
+       case ssa.OpCopy, ssa.OpMIPS64MOVVreg:
                if v.Type.IsMemory() {
                        return
                }
index e615f207bd69d961b19bbf30fb02efd1d3d49954..3c10149eabfc4a5e811d05112d76f156f8a09216 100644 (file)
@@ -132,7 +132,7 @@ func ssaGenISEL(s *gc.SSAGenState, v *ssa.Value, cr int64, r1, r2 int16) {
 
 func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        switch v.Op {
-       case ssa.OpCopy, ssa.OpPPC64MOVDconvert:
+       case ssa.OpCopy:
                t := v.Type
                if t.IsMemory() {
                        return
index 961bef5b910aead6811aee6633026d2369cd253c..eb7474e7fde7a4f51daea9b85d2c207ccd3c4b3f 100644 (file)
@@ -457,7 +457,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Reg = v.Args[0].Reg()
                gc.AddAux2(&p.To, v, sc.Off())
-       case ssa.OpCopy, ssa.OpS390XMOVDconvert, ssa.OpS390XMOVDreg:
+       case ssa.OpCopy, ssa.OpS390XMOVDreg:
                if v.Type.IsMemory() {
                        return
                }
index bde61f58cf76d0d5a8a883419b0259303167f2da..6ab90e261956a2b3dbafbbfd3f0dd41684733f41 100644 (file)
 (InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem)
 
 // Miscellaneous
-(Convert <t> x mem) -> (MOVLconvert <t> x mem)
 (IsNonNil p) -> (SETNE (TESTL p p))
 (IsInBounds idx len) -> (SETB (CMPL idx len))
 (IsSliceInBounds idx len) -> (SETBE (CMPL idx len))
index d22271f2dc09a4a049df3ad4a5590998de18d9d4..23060ef0f658a519de74eebf652d48bfdf27d5ee 100644 (file)
@@ -469,13 +469,6 @@ func init() {
                // It saves all GP registers if necessary, but may clobber others.
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
-               // MOVLconvert converts between pointers and integers.
-               // We have a special op for this so as to not confuse GC
-               // (particularly stack maps).  It takes a memory arg so it
-               // gets correctly ordered with respect to GC safepoints.
-               // arg0=ptr/int arg1=mem, output=int/ptr
-               {name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL", resultInArg0: true, zeroWidth: true},
-
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index 9ebeb989908ab2ec02542862e9544b1d7de0129a..482a1558dcce14f1939c9de054880e1cdb9fae4d 100644 (file)
 (CMOV(QEQ|QGT|QGE|QCS|QLS|LEQ|LGT|LGE|LCS|LLS|WEQ|WGT|WGE|WCS|WLS) y _ (FlagLT_UGT)) -> y
 
 // Miscellaneous
-(Convert <t> x mem) && config.PtrSize == 8 -> (MOVQconvert <t> x mem)
-(Convert <t> x mem) && config.PtrSize == 4 -> (MOVLconvert <t> x mem)
 (IsNonNil p) && config.PtrSize == 8 -> (SETNE (TESTQ p p))
 (IsNonNil p) && config.PtrSize == 4 -> (SETNE (TESTL p p))
 (IsInBounds idx len) && config.PtrSize == 8 -> (SETB (CMPQ idx len))
index bf49dc857ed27bd09f9dc9f330d7d58e23f7933a..cf15198c0c3346c76e8962eb1c06eba47640696a 100644 (file)
@@ -642,14 +642,6 @@ func init() {
                // It saves all GP registers if necessary, but may clobber others.
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
-               // MOVQconvert converts between pointers and integers.
-               // We have a special op for this so as to not confuse GC
-               // (particularly stack maps).  It takes a memory arg so it
-               // gets correctly ordered with respect to GC safepoints.
-               // arg0=ptr/int arg1=mem, output=int/ptr
-               {name: "MOVQconvert", argLength: 2, reg: gp11, asm: "MOVQ", resultInArg0: true, zeroWidth: true},
-               {name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL", resultInArg0: true, zeroWidth: true}, // amd64p32 equivalent
-
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index bb15386f2dc8c924f3b5d7d83306fe1129b4e17c..8e5ba6674938c51a9567a2527a403081209033be 100644 (file)
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
 (GetCallerSP) -> (LoweredGetCallerSP)
-(Convert x mem) -> (MOVWconvert x mem)
 
 // Absorb pseudo-ops into blocks.
 (If (Equal cc) yes no) -> (EQ cc yes no)
index 41417482e8090949371ab69c11445e0b9c99f065..d8753414d94707ed0b8c0e5d5c9e8a5d502d1506 100644 (file)
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
 (GetCallerSP) -> (LoweredGetCallerSP)
-(Convert x mem) -> (MOVDconvert x mem)
 
 // Absorb pseudo-ops into blocks.
 (If (Equal cc) yes no) -> (EQ cc yes no)
index 184e22717ee6f3b9a26fba5a83d3991caeef452c..c90d1439cdd7785bf35075b1728736d3bd4ea46d 100644 (file)
@@ -506,13 +506,6 @@ func init() {
                // LoweredGetCallerSP returns the SP of the caller of the current function.
                {name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
 
-               // MOVDconvert converts between pointers and integers.
-               // We have a special op for this so as to not confuse GC
-               // (particularly stack maps).  It takes a memory arg so it
-               // gets correctly ordered with respect to GC safepoints.
-               // arg0=ptr/int arg1=mem, output=int/ptr
-               {name: "MOVDconvert", argLength: 2, reg: gp11, asm: "MOVD"},
-
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index d668ed8c02685a1c2c2357b3802a2eaabe2c9d66..3b916e29aefa4c997de3228cd2b022ece72a630d 100644 (file)
@@ -519,13 +519,6 @@ func init() {
                // LoweredGetCallerSP returns the SP of the caller of the current function.
                {name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
 
-               // MOVWconvert converts between pointers and integers.
-               // We have a special op for this so as to not confuse GC
-               // (particularly stack maps).  It takes a memory arg so it
-               // gets correctly ordered with respect to GC safepoints.
-               // arg0=ptr/int arg1=mem, output=int/ptr
-               {name: "MOVWconvert", argLength: 2, reg: gp11, asm: "MOVW"},
-
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index 2540b76cb1a1f91d746158a375fab59af840593c..a97a74f6adb98f1c377f254af944ff492301cf66 100644 (file)
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
 (GetCallerSP) -> (LoweredGetCallerSP)
-(Convert x mem) -> (MOVWconvert x mem)
 
 (If cond yes no) -> (NE cond yes no)
 
index c34f5fd92af6ea0d47a20441defa520ff15e23f5..61705678707a7db5ea2c74e9714b693b1e9ee094 100644 (file)
 // pseudo-ops
 (GetClosurePtr) -> (LoweredGetClosurePtr)
 (GetCallerSP) -> (LoweredGetCallerSP)
-(Convert x mem) -> (MOVVconvert x mem)
 
 (If cond yes no) -> (NE cond yes no)
 
index d5cae59147820ac956bf541a702568962f5990a2..55f860f0536d6735569eb5de087fefd63fbf5cbc 100644 (file)
@@ -414,13 +414,6 @@ func init() {
                // but clobbers R31 (LR) because it's a call
                // and R23 (REGTMP).
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-               // MOVDconvert converts between pointers and integers.
-               // We have a special op for this so as to not confuse GC
-               // (particularly stack maps).  It takes a memory arg so it
-               // gets correctly ordered with respect to GC safepoints.
-               // arg0=ptr/int arg1=mem, output=int/ptr
-               {name: "MOVVconvert", argLength: 2, reg: gp11, asm: "MOVV"},
        }
 
        blocks := []blockData{
index a38f3383b9aba67e2fc766fa279765de6e64c904..e07ad745b3d3f24b54b77b15e35dfcd9e8595d01 100644 (file)
@@ -384,13 +384,6 @@ func init() {
                // but clobbers R31 (LR) because it's a call
                // and R23 (REGTMP).
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-               // MOVWconvert converts between pointers and integers.
-               // We have a special op for this so as to not confuse GC
-               // (particularly stack maps).  It takes a memory arg so it
-               // gets correctly ordered with respect to GC safepoints.
-               // arg0=ptr/int arg1=mem, output=int/ptr
-               {name: "MOVWconvert", argLength: 2, reg: gp11, asm: "MOVW"},
        }
 
        blocks := []blockData{
index b8270eae357b79e77d9a838880a083c55e8574f8..6f3e893d8dd584dbb2d9ce22d6979696468f5d17 100644 (file)
 (InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem)
 
 // Miscellaneous
-(Convert <t> x mem) -> (MOVDconvert <t> x mem)
 (GetClosurePtr) -> (LoweredGetClosurePtr)
 (GetCallerSP) -> (LoweredGetCallerSP)
 (IsNonNil ptr) -> (NotEqual (CMPconst [0] ptr))
index ecd6944b1ed85240b3bc30c83908f03a5c21ed6c..567e34ec2a9d9f064ff86b35b8e71ecf20b50b0d 100644 (file)
@@ -327,9 +327,6 @@ func init() {
                {name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
                {name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
 
-               // Convert pointer to integer, takes a memory operand for ordering.
-               {name: "MOVDconvert", argLength: 2, reg: gp11, asm: "MOVD"},
-
                {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"},                   // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
                {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{callptr, ctxt, 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
                {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{callptr}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true},            // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
index 6eba1e026419e7ff1e71e048a5e169e055c0d2d1..fe92d0a9d08fc1f098294613863b32b71511705f 100644 (file)
 (InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem)
 
 // Miscellaneous
-(Convert <t> x mem) -> (MOVDconvert <t> x mem)
 (IsNonNil p) -> (MOVDNE (MOVDconst [0]) (MOVDconst [1]) (CMPconst p [0]))
 (IsInBounds idx len) -> (MOVDLT (MOVDconst [0]) (MOVDconst [1]) (CMPU idx len))
 (IsSliceInBounds idx len) -> (MOVDLE (MOVDconst [0]) (MOVDconst [1]) (CMPU idx len))
index 3cda2774a4ca3f924db02ab4b49db2e9123cdf3c..49904023e571ebdc53ec63112b7a52de2dba3e66 100644 (file)
@@ -459,13 +459,6 @@ func init() {
                // but clobbers R14 (LR) because it's a call.
                {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R14")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
 
-               // MOVDconvert converts between pointers and integers.
-               // We have a special op for this so as to not confuse GC
-               // (particularly stack maps). It takes a memory arg so it
-               // gets correctly ordered with respect to GC safepoints.
-               // arg0=ptr/int arg1=mem, output=int/ptr
-               {name: "MOVDconvert", argLength: 2, reg: gp11sp, asm: "MOVD"},
-
                // Constant flag values. For any comparison, there are 5 possible
                // outcomes: the three from the signed total order (<,==,>) and the
                // three from the unsigned total order. The == cases overlap.
index c077b0bfcf4ae0413b66d2490e94a149403f6a11..e84903b73de77429c8d1952436cdeac3a897cfaa 100644 (file)
@@ -289,8 +289,11 @@ var genericOps = []opData{
        // We have a special op for this so as to not confuse GC
        // (particularly stack maps).  It takes a memory arg so it
        // gets correctly ordered with respect to GC safepoints.
+       // It gets compiled to nothing, so its result must in the same
+       // register as its argument. regalloc knows it can use any
+       // allocatable integer register for OpConvert.
        // arg0=ptr/int arg1=mem, output=int/ptr
-       {name: "Convert", argLength: 2},
+       {name: "Convert", argLength: 2, zeroWidth: true, resultInArg0: true},
 
        // constants. Constant values are stored in the aux or
        // auxint fields.
index 6b0ee41f64b87a332ebaa8dea4fcb25c92da1d05..5889da3ea39c26b19ef7a2db04f59ceeef96a060 100644 (file)
@@ -180,10 +180,12 @@ func genOp() {
                        }
                        if v.resultInArg0 {
                                fmt.Fprintln(w, "resultInArg0: true,")
-                               if v.reg.inputs[0] != v.reg.outputs[0] {
+                               // OpConvert's register mask is selected dynamically,
+                               // so don't try to check it in the static table.
+                               if v.name != "Convert" && v.reg.inputs[0] != v.reg.outputs[0] {
                                        log.Fatalf("%s: input[0] and output[0] must use the same registers for %s", a.name, v.name)
                                }
-                               if v.commutative && v.reg.inputs[1] != v.reg.outputs[0] {
+                               if v.name != "Convert" && v.commutative && v.reg.inputs[1] != v.reg.outputs[0] {
                                        log.Fatalf("%s: input[1] and output[0] must use the same registers for %s", a.name, v.name)
                                }
                        }
index e7c262910ace4a346a6a2b35ecee03533edd9d6e..24f927f144edb386eb18f408be7078087fb29e82 100644 (file)
@@ -21,7 +21,7 @@ func checkLower(f *Func) {
                                continue // lowered
                        }
                        switch v.Op {
-                       case OpSP, OpSB, OpInitMem, OpArg, OpPhi, OpVarDef, OpVarKill, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1:
+                       case OpSP, OpSB, OpInitMem, OpArg, OpPhi, OpVarDef, OpVarKill, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1, OpConvert:
                                continue // ok not to lower
                        case OpGetG:
                                if f.Config.hasGReg {
index 0de1ccfddec26b4dec2d21474b38ae60544bb986..3ce846837e796494735272511800571d0df0073a 100644 (file)
@@ -411,7 +411,6 @@ const (
        Op386LoweredGetCallerSP
        Op386LoweredNilCheck
        Op386LoweredWB
-       Op386MOVLconvert
        Op386FlagEQ
        Op386FlagLT_ULT
        Op386FlagLT_UGT
@@ -742,8 +741,6 @@ const (
        OpAMD64LoweredGetCallerSP
        OpAMD64LoweredNilCheck
        OpAMD64LoweredWB
-       OpAMD64MOVQconvert
-       OpAMD64MOVLconvert
        OpAMD64FlagEQ
        OpAMD64FlagLT_ULT
        OpAMD64FlagLT_UGT
@@ -1013,7 +1010,6 @@ const (
        OpARMLoweredMove
        OpARMLoweredGetClosurePtr
        OpARMLoweredGetCallerSP
-       OpARMMOVWconvert
        OpARMFlagEQ
        OpARMFlagLT_ULT
        OpARMFlagLT_UGT
@@ -1233,7 +1229,6 @@ const (
        OpARM64LoweredMove
        OpARM64LoweredGetClosurePtr
        OpARM64LoweredGetCallerSP
-       OpARM64MOVDconvert
        OpARM64FlagEQ
        OpARM64FlagLT_ULT
        OpARM64FlagLT_UGT
@@ -1355,7 +1350,6 @@ const (
        OpMIPSLoweredGetClosurePtr
        OpMIPSLoweredGetCallerSP
        OpMIPSLoweredWB
-       OpMIPSMOVWconvert
 
        OpMIPS64ADDV
        OpMIPS64ADDVconst
@@ -1468,7 +1462,6 @@ const (
        OpMIPS64LoweredGetClosurePtr
        OpMIPS64LoweredGetCallerSP
        OpMIPS64LoweredWB
-       OpMIPS64MOVVconvert
 
        OpPPC64ADD
        OpPPC64ADDconst
@@ -1598,7 +1591,6 @@ const (
        OpPPC64LoweredNilCheck
        OpPPC64LoweredRound32F
        OpPPC64LoweredRound64F
-       OpPPC64MOVDconvert
        OpPPC64CALLstatic
        OpPPC64CALLclosure
        OpPPC64CALLinter
@@ -1812,7 +1804,6 @@ const (
        OpS390XLoweredRound32F
        OpS390XLoweredRound64F
        OpS390XLoweredWB
-       OpS390XMOVDconvert
        OpS390XFlagEQ
        OpS390XFlagLT
        OpS390XFlagGT
@@ -4738,21 +4729,6 @@ var opcodeTable = [...]opInfo{
                        clobbers: 65280, // X0 X1 X2 X3 X4 X5 X6 X7
                },
        },
-       {
-               name:         "MOVLconvert",
-               argLen:       2,
-               resultInArg0: true,
-               zeroWidth:    true,
-               asm:          x86.AMOVL,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 239}, // AX CX DX BX BP SI DI
-                       },
-                       outputs: []outputInfo{
-                               {0, 239}, // AX CX DX BX BP SI DI
-                       },
-               },
-       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -9445,36 +9421,6 @@ var opcodeTable = [...]opInfo{
                        clobbers: 4294901760, // X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
                },
        },
-       {
-               name:         "MOVQconvert",
-               argLen:       2,
-               resultInArg0: true,
-               zeroWidth:    true,
-               asm:          x86.AMOVQ,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-                       },
-                       outputs: []outputInfo{
-                               {0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-                       },
-               },
-       },
-       {
-               name:         "MOVLconvert",
-               argLen:       2,
-               resultInArg0: true,
-               zeroWidth:    true,
-               asm:          x86.AMOVL,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-                       },
-                       outputs: []outputInfo{
-                               {0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
-                       },
-               },
-       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -13186,19 +13132,6 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
-       {
-               name:   "MOVWconvert",
-               argLen: 2,
-               asm:    arm.AMOVW,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
-                       },
-                       outputs: []outputInfo{
-                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
-                       },
-               },
-       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -16112,19 +16045,6 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
-       {
-               name:   "MOVDconvert",
-               argLen: 2,
-               asm:    arm64.AMOVD,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
-                       },
-                       outputs: []outputInfo{
-                               {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
-                       },
-               },
-       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -17729,19 +17649,6 @@ var opcodeTable = [...]opInfo{
                        clobbers: 140737219919872, // R31 F0 F2 F4 F6 F8 F10 F12 F14 F16 F18 F20 F22 F24 F26 F28 F30 HI LO
                },
        },
-       {
-               name:   "MOVWconvert",
-               argLen: 2,
-               asm:    mips.AMOVW,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 469762046}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 g R31
-                       },
-                       outputs: []outputInfo{
-                               {0, 335544318}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31
-                       },
-               },
-       },
 
        {
                name:        "ADDV",
@@ -19262,19 +19169,6 @@ var opcodeTable = [...]opInfo{
                        clobbers: 4611686018293170176, // R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 HI LO
                },
        },
-       {
-               name:   "MOVVconvert",
-               argLen: 2,
-               asm:    mips.AMOVV,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 234881022}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 g R31
-                       },
-                       outputs: []outputInfo{
-                               {0, 167772158}, // R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31
-                       },
-               },
-       },
 
        {
                name:        "ADD",
@@ -20977,19 +20871,6 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
-       {
-               name:   "MOVDconvert",
-               argLen: 2,
-               asm:    ppc64.AMOVD,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
-                       },
-                       outputs: []outputInfo{
-                               {0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
-                       },
-               },
-       },
        {
                name:         "CALLstatic",
                auxType:      auxSymOff,
@@ -24099,19 +23980,6 @@ var opcodeTable = [...]opInfo{
                        clobbers: 4294918144, // R14 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
                },
        },
-       {
-               name:   "MOVDconvert",
-               argLen: 2,
-               asm:    s390x.AMOVD,
-               reg: regInfo{
-                       inputs: []inputInfo{
-                               {0, 54271}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP
-                       },
-                       outputs: []outputInfo{
-                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
-                       },
-               },
-       },
        {
                name:   "FlagEQ",
                argLen: 0,
@@ -25540,9 +25408,11 @@ var opcodeTable = [...]opInfo{
                generic: true,
        },
        {
-               name:    "Convert",
-               argLen:  2,
-               generic: true,
+               name:         "Convert",
+               argLen:       2,
+               resultInArg0: true,
+               zeroWidth:    true,
+               generic:      true,
        },
        {
                name:    "ConstBool",
index 3fe170ac55c981bcc93069e1f98415c147e08263..7e35526f19130a26ef19e767d8fb42623af313ca 100644 (file)
@@ -714,6 +714,18 @@ func (s *regAllocState) compatRegs(t *types.Type) regMask {
        return m & s.allocatable
 }
 
+// regspec returns the regInfo for operation op.
+func (s *regAllocState) regspec(op Op) regInfo {
+       if op == OpConvert {
+               // OpConvert is a generic op, so it doesn't have a
+               // register set in the static table. It can use any
+               // allocatable integer register.
+               m := s.allocatable & s.f.Config.gpRegMask
+               return regInfo{inputs: []inputInfo{{regs: m}}, outputs: []outputInfo{{regs: m}}}
+       }
+       return opcodeTable[op].reg
+}
+
 func (s *regAllocState) regalloc(f *Func) {
        regValLiveSet := f.newSparseSet(f.NumValues()) // set of values that may be live in register
        defer f.retSparseSet(regValLiveSet)
@@ -1035,8 +1047,9 @@ func (s *regAllocState) regalloc(f *Func) {
                for i := len(oldSched) - 1; i >= 0; i-- {
                        v := oldSched[i]
                        prefs := desired.remove(v.ID)
-                       desired.clobber(opcodeTable[v.Op].reg.clobbers)
-                       for _, j := range opcodeTable[v.Op].reg.inputs {
+                       regspec := s.regspec(v.Op)
+                       desired.clobber(regspec.clobbers)
+                       for _, j := range regspec.inputs {
                                if countRegs(j.regs) != 1 {
                                        continue
                                }
@@ -1064,7 +1077,7 @@ func (s *regAllocState) regalloc(f *Func) {
                        if s.f.pass.debug > regDebug {
                                fmt.Printf("  processing %s\n", v.LongString())
                        }
-                       regspec := opcodeTable[v.Op].reg
+                       regspec := s.regspec(v.Op)
                        if v.Op == OpPhi {
                                f.Fatalf("phi %s not at start of block", v)
                        }
@@ -2274,10 +2287,11 @@ func (s *regAllocState) computeLive() {
                                        // desired registers back though phi nodes.
                                        continue
                                }
+                               regspec := s.regspec(v.Op)
                                // Cancel desired registers if they get clobbered.
-                               desired.clobber(opcodeTable[v.Op].reg.clobbers)
+                               desired.clobber(regspec.clobbers)
                                // Update desired registers if there are any fixed register inputs.
-                               for _, j := range opcodeTable[v.Op].reg.inputs {
+                               for _, j := range regspec.inputs {
                                        if countRegs(j.regs) != 1 {
                                                continue
                                        }
index 233cd43f69ac6f6b049558b69aa94cbff529e772..712cc9398e70cda12162da26218227ce44d47c01 100644 (file)
@@ -303,8 +303,6 @@ func rewriteValue386(v *Value) bool {
                return rewriteValue386_OpConstBool_0(v)
        case OpConstNil:
                return rewriteValue386_OpConstNil_0(v)
-       case OpConvert:
-               return rewriteValue386_OpConvert_0(v)
        case OpCvt32Fto32:
                return rewriteValue386_OpCvt32Fto32_0(v)
        case OpCvt32Fto64F:
@@ -15915,22 +15913,6 @@ func rewriteValue386_OpConstNil_0(v *Value) bool {
                return true
        }
 }
-func rewriteValue386_OpConvert_0(v *Value) bool {
-       // match: (Convert <t> x mem)
-       // cond:
-       // result: (MOVLconvert <t> x mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               v.reset(Op386MOVLconvert)
-               v.Type = t
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-}
 func rewriteValue386_OpCvt32Fto32_0(v *Value) bool {
        // match: (Cvt32Fto32 x)
        // cond:
index 30e09da3fe4d5edbbd5b1fcaa8168f791a96ec3b..e51a25527c6bcd9264994739fd4b3002f29991f7 100644 (file)
@@ -587,8 +587,6 @@ func rewriteValueAMD64(v *Value) bool {
                return rewriteValueAMD64_OpConstBool_0(v)
        case OpConstNil:
                return rewriteValueAMD64_OpConstNil_0(v)
-       case OpConvert:
-               return rewriteValueAMD64_OpConvert_0(v)
        case OpCtz32:
                return rewriteValueAMD64_OpCtz32_0(v)
        case OpCtz64:
@@ -53169,47 +53167,6 @@ func rewriteValueAMD64_OpConstNil_0(v *Value) bool {
        }
        return false
 }
-func rewriteValueAMD64_OpConvert_0(v *Value) bool {
-       b := v.Block
-       _ = b
-       config := b.Func.Config
-       _ = config
-       // match: (Convert <t> x mem)
-       // cond: config.PtrSize == 8
-       // result: (MOVQconvert <t> x mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               if !(config.PtrSize == 8) {
-                       break
-               }
-               v.reset(OpAMD64MOVQconvert)
-               v.Type = t
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (Convert <t> x mem)
-       // cond: config.PtrSize == 4
-       // result: (MOVLconvert <t> x mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               if !(config.PtrSize == 4) {
-                       break
-               }
-               v.reset(OpAMD64MOVLconvert)
-               v.Type = t
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-       return false
-}
 func rewriteValueAMD64_OpCtz32_0(v *Value) bool {
        b := v.Block
        _ = b
index 945d053f8a39269c50e426b6027d9be59b72bc62..3a0b270c8ea2906159eaba65c3941dd82f52ed66 100644 (file)
@@ -481,8 +481,6 @@ func rewriteValueARM(v *Value) bool {
                return rewriteValueARM_OpConstBool_0(v)
        case OpConstNil:
                return rewriteValueARM_OpConstNil_0(v)
-       case OpConvert:
-               return rewriteValueARM_OpConvert_0(v)
        case OpCtz32:
                return rewriteValueARM_OpCtz32_0(v)
        case OpCvt32Fto32:
@@ -17915,20 +17913,6 @@ func rewriteValueARM_OpConstNil_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM_OpConvert_0(v *Value) bool {
-       // match: (Convert x mem)
-       // cond:
-       // result: (MOVWconvert x mem)
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARMMOVWconvert)
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-}
 func rewriteValueARM_OpCtz32_0(v *Value) bool {
        b := v.Block
        _ = b
index 90cbff3a59db92e61fb6b3654bdc1eaa8e8107c9..8317316f7ef3c6df395e5a9ad68578c24053c11b 100644 (file)
@@ -379,8 +379,6 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpConstBool_0(v)
        case OpConstNil:
                return rewriteValueARM64_OpConstNil_0(v)
-       case OpConvert:
-               return rewriteValueARM64_OpConvert_0(v)
        case OpCtz32:
                return rewriteValueARM64_OpCtz32_0(v)
        case OpCtz64:
@@ -21155,20 +21153,6 @@ func rewriteValueARM64_OpConstNil_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueARM64_OpConvert_0(v *Value) bool {
-       // match: (Convert x mem)
-       // cond:
-       // result: (MOVDconvert x mem)
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpARM64MOVDconvert)
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-}
 func rewriteValueARM64_OpCtz32_0(v *Value) bool {
        b := v.Block
        _ = b
index cfd4c7306bca0deb51bfded5fe6043387592377b..ad5033176e04fa11c9dd0b37c0750354a19224e5 100644 (file)
@@ -83,8 +83,6 @@ func rewriteValueMIPS(v *Value) bool {
                return rewriteValueMIPS_OpConstBool_0(v)
        case OpConstNil:
                return rewriteValueMIPS_OpConstNil_0(v)
-       case OpConvert:
-               return rewriteValueMIPS_OpConvert_0(v)
        case OpCtz32:
                return rewriteValueMIPS_OpCtz32_0(v)
        case OpCvt32Fto32:
@@ -1163,20 +1161,6 @@ func rewriteValueMIPS_OpConstNil_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueMIPS_OpConvert_0(v *Value) bool {
-       // match: (Convert x mem)
-       // cond:
-       // result: (MOVWconvert x mem)
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpMIPSMOVWconvert)
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-}
 func rewriteValueMIPS_OpCtz32_0(v *Value) bool {
        b := v.Block
        _ = b
index 1e0fdcbc713c5db72263f44b1faf05a9981689d1..77573d784ab7fbc7a9e021cb9628feb4ac1f8b60 100644 (file)
@@ -93,8 +93,6 @@ func rewriteValueMIPS64(v *Value) bool {
                return rewriteValueMIPS64_OpConstBool_0(v)
        case OpConstNil:
                return rewriteValueMIPS64_OpConstNil_0(v)
-       case OpConvert:
-               return rewriteValueMIPS64_OpConvert_0(v)
        case OpCvt32Fto32:
                return rewriteValueMIPS64_OpCvt32Fto32_0(v)
        case OpCvt32Fto64:
@@ -1181,20 +1179,6 @@ func rewriteValueMIPS64_OpConstNil_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueMIPS64_OpConvert_0(v *Value) bool {
-       // match: (Convert x mem)
-       // cond:
-       // result: (MOVVconvert x mem)
-       for {
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpMIPS64MOVVconvert)
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-}
 func rewriteValueMIPS64_OpCvt32Fto32_0(v *Value) bool {
        // match: (Cvt32Fto32 x)
        // cond:
index b407ce4ffd101b3d7b2935b07a5254c4be81c7fd..331a8c9232b157701eac5005e736bd722487f1a7 100644 (file)
@@ -103,8 +103,6 @@ func rewriteValuePPC64(v *Value) bool {
                return rewriteValuePPC64_OpConstBool_0(v)
        case OpConstNil:
                return rewriteValuePPC64_OpConstNil_0(v)
-       case OpConvert:
-               return rewriteValuePPC64_OpConvert_0(v)
        case OpCopysign:
                return rewriteValuePPC64_OpCopysign_0(v)
        case OpCtz32:
@@ -1275,22 +1273,6 @@ func rewriteValuePPC64_OpConstNil_0(v *Value) bool {
                return true
        }
 }
-func rewriteValuePPC64_OpConvert_0(v *Value) bool {
-       // match: (Convert <t> x mem)
-       // cond:
-       // result: (MOVDconvert <t> x mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpPPC64MOVDconvert)
-               v.Type = t
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-}
 func rewriteValuePPC64_OpCopysign_0(v *Value) bool {
        // match: (Copysign x y)
        // cond:
index d3e15ac037ac1c1d41331e60f719a34f434da48e..9237a9d4e806ecd05b189695450269a30c73bca5 100644 (file)
@@ -101,8 +101,6 @@ func rewriteValueS390X(v *Value) bool {
                return rewriteValueS390X_OpConstBool_0(v)
        case OpConstNil:
                return rewriteValueS390X_OpConstNil_0(v)
-       case OpConvert:
-               return rewriteValueS390X_OpConvert_0(v)
        case OpCtz32:
                return rewriteValueS390X_OpCtz32_0(v)
        case OpCtz64:
@@ -1391,22 +1389,6 @@ func rewriteValueS390X_OpConstNil_0(v *Value) bool {
                return true
        }
 }
-func rewriteValueS390X_OpConvert_0(v *Value) bool {
-       // match: (Convert <t> x mem)
-       // cond:
-       // result: (MOVDconvert <t> x mem)
-       for {
-               t := v.Type
-               _ = v.Args[1]
-               x := v.Args[0]
-               mem := v.Args[1]
-               v.reset(OpS390XMOVDconvert)
-               v.Type = t
-               v.AddArg(x)
-               v.AddArg(mem)
-               return true
-       }
-}
 func rewriteValueS390X_OpCtz32_0(v *Value) bool {
        b := v.Block
        _ = b
index 1e0e1f9a702949bfcb908453592fc9f8089d5734..a9b95bd410a604bfd80c2cb886615f9f50f4628b 100644 (file)
@@ -615,10 +615,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Sym = gc.Duffcopy
                p.To.Offset = v.AuxInt
 
-       case ssa.Op386MOVLconvert:
-               if v.Args[0].Reg() != v.Reg() {
-                       v.Fatalf("MOVLconvert should be a no-op")
-               }
        case ssa.OpCopy: // TODO: use MOVLreg for reg->reg copies instead of OpCopy?
                if v.Type.IsMemory() {
                        return