]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fold MOV*nop and MOV*const
authorKeith Randall <khr@golang.org>
Wed, 9 Dec 2020 22:59:40 +0000 (14:59 -0800)
committerKeith Randall <khr@golang.org>
Tue, 23 Feb 2021 20:05:01 +0000 (20:05 +0000)
MOV*nop and MOV*reg seem superfluous. They are there to keep type
information around that would otherwise get thrown away. Not sure
what we need it for. I think our compiler needs a normalization of
how types are represented in SSA, especially after lowering.

MOV*nop gets in the way of some optimization rules firing, like for
load combining.

For now, just fold MOV*nop and MOV*const. It's certainly safe to
do that, as the type info on the MOV*const isn't ever useful.

R=go1.17

Change-Id: I3630a80afc2455a8e9cd9fde10c7abe05ddc3767
Reviewed-on: https://go-review.googlesource.com/c/go/+/276792
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/gen/ARM.rules
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/gen/MIPS.rules
src/cmd/compile/internal/ssa/gen/MIPS64.rules
src/cmd/compile/internal/ssa/gen/RISCV64.rules
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/rewriteRISCV64.go

index de0df363e496402389719e6f289fd0e359074c51..cbafd12a4fa063d931a66e4bad40ac67dc3fb75c 100644 (file)
 // MOVWnop doesn't emit instruction, only for ensuring the type.
 (MOVWreg x) && x.Uses == 1 => (MOVWnop x)
 
+// TODO: we should be able to get rid of MOVWnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVWnop (MOVWconst [c])) => (MOVWconst [c])
+
 // mul by constant
 (MUL x (MOVWconst [c])) && int32(c) == -1 => (RSBconst [0] x)
 (MUL _ (MOVWconst [0])) => (MOVWconst [0])
index a0e2a0d5e2722e6e88df9a8c8fc382560d95a82f..4531c38a7aa0c0e40c9d142dcd0690f9fca5012d 100644 (file)
 // MOVDnop doesn't emit instruction, only for ensuring the type.
 (MOVDreg x) && x.Uses == 1 => (MOVDnop x)
 
+// TODO: we should be able to get rid of MOVDnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVDnop (MOVDconst [c])) => (MOVDconst [c])
+
 // fold constant into arithmatic ops
 (ADD x (MOVDconst [c])) => (ADDconst [c] x)
 (SUB x (MOVDconst [c])) => (SUBconst [c] x)
index 8ad2c90ac33c59c6d9ff7e1a9fd8ca9a19babdf9..bc1ce82940b289be4cd04a6c6d78bf6886e09fc0 100644 (file)
 // MOVWnop doesn't emit instruction, only for ensuring the type.
 (MOVWreg x) && x.Uses == 1 => (MOVWnop x)
 
+// TODO: we should be able to get rid of MOVWnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVWnop (MOVWconst [c])) => (MOVWconst [c])
+
 // fold constant into arithmatic ops
 (ADD x (MOVWconst [c])) => (ADDconst [c] x)
 (SUB x (MOVWconst [c])) => (SUBconst [c] x)
index 088c9b1ac44c148ecd910e2d2b5e4aaf4e12efd5..e3f76332748957f2964a11222d021fd29c43b7b8 100644 (file)
 // MOVVnop doesn't emit instruction, only for ensuring the type.
 (MOVVreg x) && x.Uses == 1 => (MOVVnop x)
 
+// TODO: we should be able to get rid of MOVVnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVVnop (MOVVconst [c])) => (MOVVconst [c])
+
 // fold constant into arithmatic ops
 (ADDV x (MOVVconst [c])) && is32Bit(c) => (ADDVconst [c] x)
 (SUBV x (MOVVconst [c])) && is32Bit(c) => (SUBVconst [c] x)
index 15361fd37a925a82b50323e76d5920d91c79dee0..9119ebc0e8ac722fe674222653cc8216b5a5bcba 100644 (file)
 // MOVnop does not emit an instruction, only for ensuring the type.
 (MOVDreg x) && x.Uses == 1 => (MOVDnop x)
 
+// TODO: we should be able to get rid of MOVDnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVDnop (MOVDconst [c])) => (MOVDconst [c])
+
 // Fold constant into immediate instructions where possible.
 (ADD (MOVBconst [val]) x) => (ADDI [int64(val)] x)
 (ADD (MOVHconst [val]) x) => (ADDI [int64(val)] x)
index c958aae2c4abdceceb8cd39885d324ce4f6e3c18..1adbceb0ad6736f5d762b4048ddfe9b96a4976e0 100644 (file)
@@ -202,6 +202,8 @@ func rewriteValueARM(v *Value) bool {
                return rewriteValueARM_OpARMMOVWloadshiftRA(v)
        case OpARMMOVWloadshiftRL:
                return rewriteValueARM_OpARMMOVWloadshiftRL(v)
+       case OpARMMOVWnop:
+               return rewriteValueARM_OpARMMOVWnop(v)
        case OpARMMOVWreg:
                return rewriteValueARM_OpARMMOVWreg(v)
        case OpARMMOVWstore:
@@ -6501,6 +6503,21 @@ func rewriteValueARM_OpARMMOVWloadshiftRL(v *Value) bool {
        }
        return false
 }
+func rewriteValueARM_OpARMMOVWnop(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (MOVWnop (MOVWconst [c]))
+       // result: (MOVWconst [c])
+       for {
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := auxIntToInt32(v_0.AuxInt)
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = int32ToAuxInt(c)
+               return true
+       }
+       return false
+}
 func rewriteValueARM_OpARMMOVWreg(v *Value) bool {
        v_0 := v.Args[0]
        // match: (MOVWreg x)
index ff1156d9011ea2df6fb570b446f8e21b02772315..ba146c7043174e80531ca73cdc42133ee0495a1a 100644 (file)
@@ -189,6 +189,8 @@ func rewriteValueARM64(v *Value) bool {
                return rewriteValueARM64_OpARM64MOVDloadidx(v)
        case OpARM64MOVDloadidx8:
                return rewriteValueARM64_OpARM64MOVDloadidx8(v)
+       case OpARM64MOVDnop:
+               return rewriteValueARM64_OpARM64MOVDnop(v)
        case OpARM64MOVDreg:
                return rewriteValueARM64_OpARM64MOVDreg(v)
        case OpARM64MOVDstore:
@@ -9011,6 +9013,21 @@ func rewriteValueARM64_OpARM64MOVDloadidx8(v *Value) bool {
        }
        return false
 }
+func rewriteValueARM64_OpARM64MOVDnop(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (MOVDnop (MOVDconst [c]))
+       // result: (MOVDconst [c])
+       for {
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := auxIntToInt64(v_0.AuxInt)
+               v.reset(OpARM64MOVDconst)
+               v.AuxInt = int64ToAuxInt(c)
+               return true
+       }
+       return false
+}
 func rewriteValueARM64_OpARM64MOVDreg(v *Value) bool {
        v_0 := v.Args[0]
        // match: (MOVDreg x)
index 3fc552795507c256582aec4deb41a53dabf80b26..0c074364df7b4f6843ce35eca9bfabc695acf750 100644 (file)
@@ -297,6 +297,8 @@ func rewriteValueMIPS(v *Value) bool {
                return rewriteValueMIPS_OpMIPSMOVHstorezero(v)
        case OpMIPSMOVWload:
                return rewriteValueMIPS_OpMIPSMOVWload(v)
+       case OpMIPSMOVWnop:
+               return rewriteValueMIPS_OpMIPSMOVWnop(v)
        case OpMIPSMOVWreg:
                return rewriteValueMIPS_OpMIPSMOVWreg(v)
        case OpMIPSMOVWstore:
@@ -3647,6 +3649,21 @@ func rewriteValueMIPS_OpMIPSMOVWload(v *Value) bool {
        }
        return false
 }
+func rewriteValueMIPS_OpMIPSMOVWnop(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (MOVWnop (MOVWconst [c]))
+       // result: (MOVWconst [c])
+       for {
+               if v_0.Op != OpMIPSMOVWconst {
+                       break
+               }
+               c := auxIntToInt32(v_0.AuxInt)
+               v.reset(OpMIPSMOVWconst)
+               v.AuxInt = int32ToAuxInt(c)
+               return true
+       }
+       return false
+}
 func rewriteValueMIPS_OpMIPSMOVWreg(v *Value) bool {
        v_0 := v.Args[0]
        // match: (MOVWreg x)
index d78f6089afff28f780226dbb8afe515d69d14363..073cf8726cca42ca72b252a5aec59dc5586cab7f 100644 (file)
@@ -339,6 +339,8 @@ func rewriteValueMIPS64(v *Value) bool {
                return rewriteValueMIPS64_OpMIPS64MOVHstorezero(v)
        case OpMIPS64MOVVload:
                return rewriteValueMIPS64_OpMIPS64MOVVload(v)
+       case OpMIPS64MOVVnop:
+               return rewriteValueMIPS64_OpMIPS64MOVVnop(v)
        case OpMIPS64MOVVreg:
                return rewriteValueMIPS64_OpMIPS64MOVVreg(v)
        case OpMIPS64MOVVstore:
@@ -3584,6 +3586,21 @@ func rewriteValueMIPS64_OpMIPS64MOVVload(v *Value) bool {
        }
        return false
 }
+func rewriteValueMIPS64_OpMIPS64MOVVnop(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (MOVVnop (MOVVconst [c]))
+       // result: (MOVVconst [c])
+       for {
+               if v_0.Op != OpMIPS64MOVVconst {
+                       break
+               }
+               c := auxIntToInt64(v_0.AuxInt)
+               v.reset(OpMIPS64MOVVconst)
+               v.AuxInt = int64ToAuxInt(c)
+               return true
+       }
+       return false
+}
 func rewriteValueMIPS64_OpMIPS64MOVVreg(v *Value) bool {
        v_0 := v.Args[0]
        // match: (MOVVreg x)
index 1abdf1aa0639d91880232ca93c3e8d0d1c46631e..bc47d76e87d3f43ae79db948e361ccb3aa8ac8a3 100644 (file)
@@ -435,6 +435,8 @@ func rewriteValueRISCV64(v *Value) bool {
                return rewriteValueRISCV64_OpRISCV64MOVDconst(v)
        case OpRISCV64MOVDload:
                return rewriteValueRISCV64_OpRISCV64MOVDload(v)
+       case OpRISCV64MOVDnop:
+               return rewriteValueRISCV64_OpRISCV64MOVDnop(v)
        case OpRISCV64MOVDreg:
                return rewriteValueRISCV64_OpRISCV64MOVDreg(v)
        case OpRISCV64MOVDstore:
@@ -3349,6 +3351,21 @@ func rewriteValueRISCV64_OpRISCV64MOVDload(v *Value) bool {
        }
        return false
 }
+func rewriteValueRISCV64_OpRISCV64MOVDnop(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (MOVDnop (MOVDconst [c]))
+       // result: (MOVDconst [c])
+       for {
+               if v_0.Op != OpRISCV64MOVDconst {
+                       break
+               }
+               c := auxIntToInt64(v_0.AuxInt)
+               v.reset(OpRISCV64MOVDconst)
+               v.AuxInt = int64ToAuxInt(c)
+               return true
+       }
+       return false
+}
 func rewriteValueRISCV64_OpRISCV64MOVDreg(v *Value) bool {
        v_0 := v.Args[0]
        // match: (MOVDreg x)