]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal: Optimization with RBIT and REV
authorBen Shi <powerman1st@163.com>
Tue, 24 Jan 2017 09:48:58 +0000 (09:48 +0000)
committerCherry Zhang <cherryyz@google.com>
Fri, 31 Mar 2017 15:10:24 +0000 (15:10 +0000)
By checking GOARM in ssa/gen/ARM.rules, each intermediate operator
can be implemented via different instruction serials.

It is up to the user to choose between compitability and efficiency.

The Bswap32(x) is optimized to REV(x) when GOARM >= 6.
The CTZ(x) is optimized to CLZ(RBIT x) when GOARM == 7.

Change-Id: Ie9ee645fa39333fa79ad84ed4d1cefac30422814
Reviewed-on: https://go-review.googlesource.com/35610
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
16 files changed:
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/gen/rulegen.go
src/cmd/compile/internal/ssa/opGen.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/ssa/rewritedec.go
src/cmd/compile/internal/ssa/rewritedec64.go
src/cmd/compile/internal/ssa/rewritegeneric.go

index 47da33613e02bb9e295f29a8e5553cb69f2c0309..d31379a2d67b07d652e1b084332f55cef15b8f82 100644 (file)
@@ -582,6 +582,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                fallthrough
        case ssa.OpARMMVN,
                ssa.OpARMCLZ,
+               ssa.OpARMREV,
+               ssa.OpARMRBIT,
                ssa.OpARMSQRTD,
                ssa.OpARMNEGF,
                ssa.OpARMNEGD,
index 5ab695c76bb5ebd9149dc08013e0a94f7b1113df..92f2c0b3022fc3c44bef0c20bcf35120c2679c46 100644 (file)
 
 (Sqrt x) -> (SQRTD x)
 
-// count trailing zero
+// count trailing zero for ARMv5 and ARMv6
 // 32 - CLZ(x&-x - 1)
-(Ctz32 <t> x) -> (RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
+(Ctz32 <t> x) && obj.GOARM<=6 -> (RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
+
+// count trailing zero for ARMv7
+(Ctz32 <t> x) && obj.GOARM==7 -> (CLZ <t> (RBIT <t> x))
 
 // bit length
 (BitLen32 <t> x) -> (RSBconst [32] (CLZ <t> x))
 
-// byte swap
+// byte swap for ARMv5
 // let (a, b, c, d) be the bytes of x from high to low
 // t1 = x right rotate 16 bits -- (c,   d,   a,   b  )
 // t2 = x ^ t1                 -- (a^c, b^d, a^c, b^d)
 // t5 = x right rotate 8 bits  -- (d,   a,   b,   c  )
 // result = t4 ^ t5            -- (d,   c,   b,   a  )
 // using shifted ops this can be done in 4 instructions.
-(Bswap32 <t> x) ->
+(Bswap32 <t> x) && obj.GOARM==5 ->
        (XOR <t>
                (SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])
                (SRRconst <t> x [8]))
 
+// byte swap for ARMv6 and above
+(Bswap32 x) && obj.GOARM>=6 -> (REV x)
+
 // boolean ops -- booleans are represented with 0=false, 1=true
 (AndB x y) -> (AND x y)
 (OrB x y) -> (OR x y)
index f99df3440d031b6d90539a4377f27e5a368735f1..02cb9ce5d7256166a0e22668972976744e5a419b 100644 (file)
@@ -197,7 +197,9 @@ func init() {
                {name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
                {name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
 
-               {name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"}, // count leading zero
+               {name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},   // count leading zero
+               {name: "REV", argLength: 1, reg: gp11, asm: "REV"},   // reverse byte order
+               {name: "RBIT", argLength: 1, reg: gp11, asm: "RBIT"}, // reverse bit order
 
                // shifts
                {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                    // arg0 << arg1, shift amount is mod 256
index beabca97d0ee1fa677359d56ce60ec947fc8a307..0e478d052ffc5f5937ebf9d9a509ae68cc52143c 100644 (file)
@@ -153,7 +153,9 @@ func genRules(arch arch) {
        fmt.Fprintln(w)
        fmt.Fprintln(w, "package ssa")
        fmt.Fprintln(w, "import \"math\"")
+       fmt.Fprintln(w, "import \"cmd/internal/obj\"")
        fmt.Fprintln(w, "var _ = math.MinInt8 // in case not otherwise used")
+       fmt.Fprintln(w, "var _ = obj.ANOP     // in case not otherwise used")
 
        // Main rewrite routine is a switch on v.Op.
        fmt.Fprintf(w, "func rewriteValue%s(v *Value) bool {\n", arch.name)
index ce6988e0142afb12e63190371ff60988d2381550..74ad2d4eb16f38578ae879116d7f8d4f808941d5 100644 (file)
@@ -696,6 +696,8 @@ const (
        OpARMNEGD
        OpARMSQRTD
        OpARMCLZ
+       OpARMREV
+       OpARMRBIT
        OpARMSLL
        OpARMSLLconst
        OpARMSRL
@@ -8443,6 +8445,32 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "REV",
+               argLen: 1,
+               asm:    arm.AREV,
+               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:   "RBIT",
+               argLen: 1,
+               asm:    arm.ARBIT,
+               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:   "SLL",
                argLen: 2,
index ba5288de2a13da35530c6c7cb788d94ea4560c64..93304858131bc50084d558da78a4af655c510cb3 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValue386(v *Value) bool {
        switch v.Op {
        case Op386ADCL:
index e31d3b453a8324affa7a089b5021d21a1cdd026a..405be0cc9ac378d35e4f6628c1b06fcc67d90c1a 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValueAMD64(v *Value) bool {
        switch v.Op {
        case OpAMD64ADDL:
index 0b554d79a411fe442787964489f85bcbb4681a17..714ec4937aec0ddf48aeb4de8df596949db37a8a 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValueARM(v *Value) bool {
        switch v.Op {
        case OpARMADC:
@@ -12904,11 +12906,14 @@ func rewriteValueARM_OpBswap32(v *Value) bool {
        b := v.Block
        _ = b
        // match: (Bswap32 <t> x)
-       // cond:
+       // cond: obj.GOARM==5
        // result: (XOR <t>             (SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])          (SRRconst <t> x [8]))
        for {
                t := v.Type
                x := v.Args[0]
+               if !(obj.GOARM == 5) {
+                       break
+               }
                v.reset(OpARMXOR)
                v.Type = t
                v0 := b.NewValue0(v.Pos, OpARMSRLconst, t)
@@ -12930,6 +12935,19 @@ func rewriteValueARM_OpBswap32(v *Value) bool {
                v.AddArg(v4)
                return true
        }
+       // match: (Bswap32 x)
+       // cond: obj.GOARM>=6
+       // result: (REV x)
+       for {
+               x := v.Args[0]
+               if !(obj.GOARM >= 6) {
+                       break
+               }
+               v.reset(OpARMREV)
+               v.AddArg(x)
+               return true
+       }
+       return false
 }
 func rewriteValueARM_OpClosureCall(v *Value) bool {
        // match: (ClosureCall [argwid] entry closure mem)
@@ -13074,11 +13092,14 @@ func rewriteValueARM_OpCtz32(v *Value) bool {
        b := v.Block
        _ = b
        // match: (Ctz32 <t> x)
-       // cond:
+       // cond: obj.GOARM<=6
        // result: (RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
        for {
                t := v.Type
                x := v.Args[0]
+               if !(obj.GOARM <= 6) {
+                       break
+               }
                v.reset(OpARMRSBconst)
                v.AuxInt = 32
                v0 := b.NewValue0(v.Pos, OpARMCLZ, t)
@@ -13095,6 +13116,23 @@ func rewriteValueARM_OpCtz32(v *Value) bool {
                v.AddArg(v0)
                return true
        }
+       // match: (Ctz32 <t> x)
+       // cond: obj.GOARM==7
+       // result: (CLZ <t> (RBIT <t> x))
+       for {
+               t := v.Type
+               x := v.Args[0]
+               if !(obj.GOARM == 7) {
+                       break
+               }
+               v.reset(OpARMCLZ)
+               v.Type = t
+               v0 := b.NewValue0(v.Pos, OpARMRBIT, t)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       return false
 }
 func rewriteValueARM_OpCvt32Fto32(v *Value) bool {
        // match: (Cvt32Fto32 x)
index 009e36b90fb283bcd3bfdc72ea76dfa8b8ded1df..d276cbcf103ac3017c0a520e500d755ad7c4c4f7 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValueARM64(v *Value) bool {
        switch v.Op {
        case OpARM64ADD:
index 19144108e75224c0dca1f714a2ebf099fffda476..0f8321440b9f73639dc6e47762a18f54f1844af2 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValueMIPS(v *Value) bool {
        switch v.Op {
        case OpAdd16:
index e0f16a9f8721f3d4a33640875ca849e8838a333f..8c134319979f765821873f7b00e108200398f5d1 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValueMIPS64(v *Value) bool {
        switch v.Op {
        case OpAdd16:
index 785fbd211ff1666dddfaa3fadbef80aa3efee0f2..1c9a8f26679c05b5ee5ccd34f291c03ac7fa7e78 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValuePPC64(v *Value) bool {
        switch v.Op {
        case OpAdd16:
index 6740fe4cad971bd6c02fb0ffc86804909293542e..9db644570fe240ffb3c09f26226869fd35a4dd05 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValueS390X(v *Value) bool {
        switch v.Op {
        case OpAdd16:
index 2782316c7ee836c203dec7fccac3c0fc0a3caeff..f82a26a417b7684b74a47e84caca014a5758cd7b 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValuedec(v *Value) bool {
        switch v.Op {
        case OpComplexImag:
index 9e7802d431e2d054cfafdff870909d6cf023e93b..224bb9426236886ea4805820b339c547e9e68aae 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValuedec64(v *Value) bool {
        switch v.Op {
        case OpAdd64:
index 8ab751797b493127c61e0d9e3f0718947dd2e9a2..685d1479783c32a300c1f3aee2459487d2778f38 100644 (file)
@@ -4,8 +4,10 @@
 package ssa
 
 import "math"
+import "cmd/internal/obj"
 
 var _ = math.MinInt8 // in case not otherwise used
+var _ = obj.ANOP     // in case not otherwise used
 func rewriteValuegeneric(v *Value) bool {
        switch v.Op {
        case OpAdd16: