]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize ARM's math.bits.RotateLeft32
authorBen Shi <powerman1st@163.com>
Fri, 2 Aug 2019 02:20:38 +0000 (02:20 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 28 Aug 2019 15:41:58 +0000 (15:41 +0000)
This CL optimizes math.bits.RotateLeft32 to inline
"MOVW Rx@>Ry, Rd" on ARM.

The benchmark results of math/bits show some improvements.
name               old time/op  new time/op  delta
RotateLeft-4       9.42ns ± 0%  6.91ns ± 0%  -26.66%  (p=0.000 n=40+33)
RotateLeft8-4      8.79ns ± 0%  8.79ns ± 0%   -0.04%  (p=0.000 n=40+31)
RotateLeft16-4     8.79ns ± 0%  8.79ns ± 0%   -0.04%  (p=0.000 n=40+32)
RotateLeft32-4     8.16ns ± 0%  7.54ns ± 0%   -7.68%  (p=0.000 n=40+40)
RotateLeft64-4     15.7ns ± 0%  15.7ns ± 0%     ~     (all equal)

updates #31265

Change-Id: I77bc1c2c702d5323fc7cad5264a8e2d5666bf712
Reviewed-on: https://go-review.googlesource.com/c/go/+/188697
Run-TryBot: Ben Shi <powerman1st@163.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/gc/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
test/codegen/mathbits.go

index 0b798a52b98f6907236b2d3b8d7eaffa4dc5fae0..ab0f4171176906ed5793ac258380a5738af7d4ae 100644 (file)
@@ -224,6 +224,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.Reg = r1
                p.To.Type = obj.TYPE_REG
                p.To.Reg = r
+       case ssa.OpARMSRR:
+               genregshift(s, arm.AMOVW, 0, v.Args[0].Reg(), v.Args[1].Reg(), v.Reg(), arm.SHIFT_RR)
        case ssa.OpARMMULAF, ssa.OpARMMULAD, ssa.OpARMMULSF, ssa.OpARMMULSD:
                r := v.Reg()
                r0 := v.Args[0].Reg()
index e1c464b843ef03590bf4e47b86d4434bf48006f6..a911b175e8050f8396de5bc5a4c982d73e7aa289 100644 (file)
@@ -3504,7 +3504,7 @@ func init() {
                func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
                        return s.newValue2(ssa.OpRotateLeft32, types.Types[TUINT32], args[0], args[1])
                },
-               sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64)
+               sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64)
        addF("math/bits", "RotateLeft64",
                func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
                        return s.newValue2(ssa.OpRotateLeft64, types.Types[TUINT64], args[0], args[1])
index 87a91b126147fd2b5edcb0f885433e43f2b8a2eb..a3ee9046c5b8299ea7319a4e7561ff9a49cf1b07 100644 (file)
 (RotateLeft32 x (MOVWconst [c])) -> (SRRconst [-c&31] x)
 (RotateLeft16 <t> x (MOVWconst [c])) -> (Or16 (Lsh16x32 <t> x (MOVWconst [c&15])) (Rsh16Ux32 <t> x (MOVWconst [-c&15])))
 (RotateLeft8 <t> x (MOVWconst [c])) -> (Or8 (Lsh8x32 <t> x (MOVWconst [c&7])) (Rsh8Ux32 <t> x (MOVWconst [-c&7])))
+(RotateLeft32 x y) -> (SRR x (RSBconst [0] <y.Type> y))
 
 // ((x>>8) | (x<<8)) -> (REV16 x), the type of x is uint16, "|" can also be "^" or "+".
 // UBFX instruction is supported by ARMv6T2, ARMv7 and above versions, REV16 is supported by
index 484f6cfe71b4ca3c2f1d9a92aa697dd540b2d8b9..eb0f671d0dd50f8b9e906472d33d35ec7a6023b6 100644 (file)
@@ -225,6 +225,7 @@ func init() {
                {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned
                {name: "SRA", argLength: 2, reg: gp21, asm: "SRA"},                    // arg0 >> arg1, signed, shift amount is mod 256
                {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed
+               {name: "SRR", argLength: 2, reg: gp21},                                // arg0 right rotate by arg1 bits
                {name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"},             // arg0 right rotate by auxInt bits
 
                {name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt
index f316ea16e67321a85d5d7e889ba536af5bc06416..d692ed21e80b7383870c78d56fa00ada10d51d14 100644 (file)
@@ -937,6 +937,7 @@ const (
        OpARMSRLconst
        OpARMSRA
        OpARMSRAconst
+       OpARMSRR
        OpARMSRRconst
        OpARMADDshiftLL
        OpARMADDshiftRL
@@ -12448,6 +12449,19 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "SRR",
+               argLen: 2,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 22527}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {1, 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:    "SRRconst",
                auxType: auxInt32,
index 8b569781c5f0a524731fa4ef1f884dcf12bda265..78227c1b1ff2ced39a0348b63a005c39210ef819 100644 (file)
@@ -20242,6 +20242,7 @@ func rewriteValueARM_OpRotateLeft16_0(v *Value) bool {
        return false
 }
 func rewriteValueARM_OpRotateLeft32_0(v *Value) bool {
+       b := v.Block
        // match: (RotateLeft32 x (MOVWconst [c]))
        // cond:
        // result: (SRRconst [-c&31] x)
@@ -20258,7 +20259,20 @@ func rewriteValueARM_OpRotateLeft32_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       return false
+       // match: (RotateLeft32 x y)
+       // cond:
+       // result: (SRR x (RSBconst [0] <y.Type> y))
+       for {
+               y := v.Args[1]
+               x := v.Args[0]
+               v.reset(OpARMSRR)
+               v.AddArg(x)
+               v0 := b.NewValue0(v.Pos, OpARMRSBconst, y.Type)
+               v0.AuxInt = 0
+               v0.AddArg(y)
+               v.AddArg(v0)
+               return true
+       }
 }
 func rewriteValueARM_OpRotateLeft8_0(v *Value) bool {
        b := v.Block
index 0d94bd1bc8f26f19d6f69e25e6fbee1f06be4e1a..ea90e3a50e18136aa79ebec15f733efd633a06d5 100644 (file)
@@ -208,6 +208,7 @@ func RotateLeft64(n uint64) uint64 {
 
 func RotateLeft32(n uint32) uint32 {
        // amd64:"ROLL" 386:"ROLL"
+       // arm:`MOVW\tR[0-9]+@>[$]23`
        // arm64:"RORW"
        // ppc64:"ROTLW"
        // ppc64le:"ROTLW"
@@ -244,6 +245,7 @@ func RotateLeftVariable64(n uint64, m int) uint64 {
 }
 
 func RotateLeftVariable32(n uint32, m int) uint32 {
+       // arm:`MOVW\tR[0-9]+@>R[0-9]+`
        // amd64:"ROLL"
        // arm64:"RORW"
        // ppc64:"ROTLW"