]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize ARM with more efficient MOVB/MOVBU/MOVH/MOVHU
authorBen Shi <powerman1st@163.com>
Thu, 24 Aug 2017 10:51:34 +0000 (10:51 +0000)
committerCherry Zhang <cherryyz@google.com>
Mon, 28 Aug 2017 16:10:27 +0000 (16:10 +0000)
Like the indexed MOVW (MOVWloadidx/MOVWstoreidx) used in current
ARM backend, the indexed MOVB/MOVBU/MOVH/MOVHU can also be used to
generate further optimized ARM code.

My patch implements this optimization. Here are some contrast test
results against the original go compiler.

1. The total size of all .a files in pkg/ shrinks by 0.03%.

2. The compilecmp benchmark shows a little decline.
name        old time/op       new time/op       delta
Template          2.35s ± 1%        2.37s ± 3%  +0.94%  (p=0.006 n=19+19)
Unicode           1.33s ± 3%        1.33s ± 2%    ~     (p=0.158 n=20+18)
GoTypes           7.86s ± 2%        7.84s ± 1%    ~     (p=0.284 n=19+18)
Compiler          37.5s ± 1%        37.7s ± 2%    ~     (p=0.101 n=20+19)
SSA               83.4s ± 2%        83.6s ± 2%    ~     (p=0.231 n=20+20)
Flate             1.46s ± 2%        1.45s ± 1%    ~     (p=0.097 n=20+17)
GoParser          1.86s ± 2%        1.86s ± 4%    ~     (p=0.738 n=20+20)
Reflect           5.10s ± 1%        5.11s ± 1%    ~     (p=0.290 n=20+18)
Tar               1.78s ± 2%        1.77s ± 2%    ~     (p=0.166 n=19+20)
XML               2.61s ± 2%        2.61s ± 2%    ~     (p=0.665 n=19+19)
[Geo mean]        4.67s             4.68s       +0.16%

name        old user-time/op  new user-time/op  delta
Template          2.79s ± 3%        2.80s ± 2%    ~     (p=0.662 n=20+20)
Unicode           1.62s ± 3%        1.64s ± 4%    ~     (p=0.252 n=20+20)
GoTypes           9.58s ± 2%        9.62s ± 2%    ~     (p=0.250 n=20+20)
Compiler          46.2s ± 1%        46.2s ± 1%    ~     (p=0.602 n=20+19)
SSA                108s ± 1%         108s ± 2%    ~     (p=0.242 n=18+20)
Flate             1.69s ± 3%        1.69s ± 4%    ~     (p=0.470 n=20+20)
GoParser          2.16s ± 3%        2.20s ± 4%  +1.70%  (p=0.005 n=19+20)
Reflect           6.02s ± 2%        6.02s ± 2%    ~     (p=0.700 n=20+17)
Tar               2.11s ± 2%        2.11s ± 3%    ~     (p=0.480 n=18+20)
XML               3.07s ± 2%        3.11s ± 4%  +1.50%  (p=0.043 n=20+20)
[Geo mean]        5.61s             5.64s       +0.55%

name        old text-bytes    new text-bytes    delta
HelloSize         586kB ± 0%        586kB ± 0%    ~     (all equal)

name        old data-bytes    new data-bytes    delta
HelloSize        5.46kB ± 0%       5.46kB ± 0%    ~     (all equal)

name        old bss-bytes     new bss-bytes     delta
HelloSize        72.9kB ± 0%       72.9kB ± 0%    ~     (all equal)

name        old exe-bytes     new exe-bytes     delta
HelloSize        1.03MB ± 0%       1.03MB ± 0%    ~     (all equal)

3. The go1 benchmark shows improvement totally, and even more than 10%
improvement in the test case Revcomp.
name                     old time/op    new time/op    delta
BinaryTree17-4              42.0s ± 1%     41.5s ± 1%   -1.32%  (p=0.000 n=39+40)
Fannkuch11-4                24.1s ± 1%     23.6s ± 0%   -2.38%  (p=0.000 n=40+40)
FmtFprintfEmpty-4           843ns ± 0%     839ns ± 1%   -0.46%  (p=0.000 n=33+40)
FmtFprintfString-4         1.44µs ± 1%    1.37µs ± 1%   -5.48%  (p=0.000 n=40+35)
FmtFprintfInt-4            1.44µs ± 1%    1.41µs ± 2%   -1.50%  (p=0.000 n=40+40)
FmtFprintfIntInt-4         2.07µs ± 1%    2.06µs ± 0%   -0.78%  (p=0.000 n=40+40)
FmtFprintfPrefixedInt-4    2.50µs ± 1%    2.33µs ± 1%   -6.85%  (p=0.000 n=40+40)
FmtFprintfFloat-4          4.36µs ± 1%    4.34µs ± 0%   -0.39%  (p=0.017 n=40+40)
FmtManyArgs-4              8.11µs ± 0%    8.00µs ± 0%   -1.37%  (p=0.000 n=40+40)
GobDecode-4                 105ms ± 2%     103ms ± 2%   -2.17%  (p=0.000 n=39+39)
GobEncode-4                90.1ms ± 2%    88.6ms ± 1%   -1.67%  (p=0.000 n=40+39)
Gzip-4                      4.18s ± 1%     4.09s ± 1%   -2.03%  (p=0.000 n=40+40)
Gunzip-4                    608ms ± 1%     603ms ± 1%   -0.86%  (p=0.000 n=40+34)
HTTPClientServer-4          674µs ± 3%     661µs ± 2%   -1.82%  (p=0.000 n=40+39)
JSONEncode-4                256ms ± 1%     243ms ± 0%   -5.11%  (p=0.000 n=39+31)
JSONDecode-4                915ms ± 1%     904ms ± 1%   -1.18%  (p=0.000 n=40+36)
Mandelbrot200-4            49.2ms ± 0%    49.3ms ± 0%     ~     (p=0.254 n=34+40)
GoParse-4                  46.9ms ± 2%    46.9ms ± 1%     ~     (p=0.737 n=40+39)
RegexpMatchEasy0_32-4      1.28µs ± 1%    1.27µs ± 1%   -0.71%  (p=0.000 n=40+40)
RegexpMatchEasy0_1K-4      7.86µs ± 4%    7.67µs ± 4%   -2.46%  (p=0.000 n=38+40)
RegexpMatchEasy1_32-4      1.28µs ± 1%    1.28µs ± 1%   -0.54%  (p=0.000 n=40+40)
RegexpMatchEasy1_1K-4      10.4µs ± 2%    10.3µs ± 2%   -0.88%  (p=0.003 n=40+39)
RegexpMatchMedium_32-4     2.05µs ± 0%    2.04µs ± 0%   -0.34%  (p=0.000 n=40+33)
RegexpMatchMedium_1K-4      541µs ± 1%     535µs ± 1%   -1.02%  (p=0.000 n=40+38)
RegexpMatchHard_32-4       29.3µs ± 1%    29.1µs ± 1%   -0.51%  (p=0.000 n=40+40)
RegexpMatchHard_1K-4        881µs ± 1%     871µs ± 1%   -1.15%  (p=0.000 n=40+40)
Revcomp-4                  81.7ms ± 2%    67.5ms ± 2%  -17.37%  (p=0.000 n=39+39)
Template-4                  1.05s ± 1%     1.08s ± 2%   +3.67%  (p=0.000 n=40+40)
TimeParse-4                7.24µs ± 1%    7.09µs ± 1%   -2.13%  (p=0.000 n=40+40)
TimeFormat-4               13.2µs ± 1%    13.1µs ± 0%   -0.31%  (p=0.007 n=40+31)
[Geo mean]                  733µs          718µs        -2.03%

name                     old speed      new speed      delta
GobDecode-4              7.28MB/s ± 2%  7.44MB/s ± 2%   +2.23%  (p=0.000 n=39+39)
GobEncode-4              8.52MB/s ± 2%  8.67MB/s ± 1%   +1.70%  (p=0.000 n=40+39)
Gzip-4                   4.65MB/s ± 1%  4.74MB/s ± 1%   +1.94%  (p=0.000 n=37+40)
Gunzip-4                 31.9MB/s ± 1%  32.2MB/s ± 1%   +0.90%  (p=0.000 n=40+36)
JSONEncode-4             7.57MB/s ± 1%  7.98MB/s ± 0%   +5.41%  (p=0.000 n=40+31)
JSONDecode-4             2.12MB/s ± 1%  2.15MB/s ± 1%   +1.23%  (p=0.000 n=40+40)
GoParse-4                1.23MB/s ± 1%  1.23MB/s ± 1%     ~     (p=0.769 n=39+40)
RegexpMatchEasy0_32-4    25.0MB/s ± 1%  25.2MB/s ± 1%   +0.71%  (p=0.000 n=40+40)
RegexpMatchEasy0_1K-4     130MB/s ± 5%   134MB/s ± 4%   +2.53%  (p=0.000 n=38+40)
RegexpMatchEasy1_32-4    24.9MB/s ± 1%  25.1MB/s ± 1%   +0.55%  (p=0.000 n=40+40)
RegexpMatchEasy1_1K-4    98.5MB/s ± 2%  99.4MB/s ± 2%   +0.88%  (p=0.003 n=40+39)
RegexpMatchMedium_32-4    490kB/s ± 0%   490kB/s ± 0%     ~     (all equal)
RegexpMatchMedium_1K-4   1.89MB/s ± 1%  1.91MB/s ± 1%   +1.02%  (p=0.000 n=40+38)
RegexpMatchHard_32-4     1.10MB/s ± 1%  1.10MB/s ± 0%   +0.41%  (p=0.000 n=40+33)
RegexpMatchHard_1K-4     1.16MB/s ± 1%  1.17MB/s ± 1%   +1.21%  (p=0.000 n=40+40)
Revcomp-4                31.1MB/s ± 2%  37.6MB/s ± 2%  +21.03%  (p=0.000 n=39+39)
Template-4               1.86MB/s ± 1%  1.79MB/s ± 1%   -3.51%  (p=0.000 n=40+38)
[Geo mean]               6.66MB/s       6.80MB/s        +2.13%

fixes #21492

Change-Id: Ia26e7ca393f0a5f31de240e8ff9a220453ca7e0d
Reviewed-on: https://go-review.googlesource.com/58450
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

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/opGen.go
src/cmd/compile/internal/ssa/rewriteARM.go

index 93abee3da0f09b2aadb4a88bd42a8482f92864dc..d0d864d25ddd2d6e29a6e8db5cb8743fac02db5a 100644 (file)
@@ -516,7 +516,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Reg = v.Args[0].Reg()
                gc.AddAux(&p.To, v)
-       case ssa.OpARMMOVWloadidx:
+       case ssa.OpARMMOVWloadidx, ssa.OpARMMOVBUloadidx, ssa.OpARMMOVBloadidx, ssa.OpARMMOVHUloadidx, ssa.OpARMMOVHloadidx:
                // this is just shift 0 bits
                fallthrough
        case ssa.OpARMMOVWloadshiftLL:
@@ -528,7 +528,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpARMMOVWloadshiftRA:
                p := genshift(s, v.Op.Asm(), 0, v.Args[1].Reg(), v.Reg(), arm.SHIFT_AR, v.AuxInt)
                p.From.Reg = v.Args[0].Reg()
-       case ssa.OpARMMOVWstoreidx:
+       case ssa.OpARMMOVWstoreidx, ssa.OpARMMOVBstoreidx, ssa.OpARMMOVHstoreidx:
                // this is just shift 0 bits
                fallthrough
        case ssa.OpARMMOVWstoreshiftLL:
index d66e50f17a4324cd0b176a43173b3d8a74c690f1..b80747ad31600993ef9b21491815cdcf933eb30a 100644 (file)
 (MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
 (MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
 (MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) -> x
+(MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVBUreg x)
+(MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVBreg x)
+(MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVHUreg x)
+(MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) -> (MOVHreg x)
 
 // fold constant into arithmatic ops
 (ADD x (MOVWconst [c])) -> (ADDconst [c] x)
 (MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftLL ptr idx [c] val mem)
 (MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftRL ptr idx [c] val mem)
 (MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil && !config.nacl -> (MOVWstoreshiftRA ptr idx [c] val mem)
+(MOVBUload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVBUloadidx ptr idx mem)
+(MOVBload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVBloadidx ptr idx mem)
+(MOVBstore [0] {sym} (ADD ptr idx) val mem) && sym == nil && !config.nacl -> (MOVBstoreidx ptr idx val mem)
+(MOVHUload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVHUloadidx ptr idx mem)
+(MOVHload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVHloadidx ptr idx mem)
+(MOVHstore [0] {sym} (ADD ptr idx) val mem) && sym == nil && !config.nacl -> (MOVHstoreidx ptr idx val mem)
 
 // constant folding in indexed loads and stores
 (MOVWloadidx ptr (MOVWconst [c]) mem) -> (MOVWload [c] ptr mem)
 (MOVWloadidx (MOVWconst [c]) ptr mem) -> (MOVWload [c] ptr mem)
+(MOVBloadidx ptr (MOVWconst [c]) mem) -> (MOVBload [c] ptr mem)
+(MOVBloadidx (MOVWconst [c]) ptr mem) -> (MOVBload [c] ptr mem)
+(MOVBUloadidx ptr (MOVWconst [c]) mem) -> (MOVBUload [c] ptr mem)
+(MOVBUloadidx (MOVWconst [c]) ptr mem) -> (MOVBUload [c] ptr mem)
+(MOVHUloadidx ptr (MOVWconst [c]) mem) -> (MOVHUload [c] ptr mem)
+(MOVHUloadidx (MOVWconst [c]) ptr mem) -> (MOVHUload [c] ptr mem)
+(MOVHloadidx ptr (MOVWconst [c]) mem) -> (MOVHload [c] ptr mem)
+(MOVHloadidx (MOVWconst [c]) ptr mem) -> (MOVHload [c] ptr mem)
 
 (MOVWstoreidx ptr (MOVWconst [c]) val mem) -> (MOVWstore [c] ptr val mem)
 (MOVWstoreidx (MOVWconst [c]) ptr val mem) -> (MOVWstore [c] ptr val mem)
+(MOVBstoreidx ptr (MOVWconst [c]) val mem) -> (MOVBstore [c] ptr val mem)
+(MOVBstoreidx (MOVWconst [c]) ptr val mem) -> (MOVBstore [c] ptr val mem)
+(MOVHstoreidx ptr (MOVWconst [c]) val mem) -> (MOVHstore [c] ptr val mem)
+(MOVHstoreidx (MOVWconst [c]) ptr val mem) -> (MOVHstore [c] ptr val mem)
 
 (MOVWloadidx ptr (SLLconst idx [c]) mem) -> (MOVWloadshiftLL ptr idx [c] mem)
 (MOVWloadidx (SLLconst idx [c]) ptr mem) -> (MOVWloadshiftLL ptr idx [c] mem)
index 40be5d66477768680fb9d81d6db259d726ff94fd..8cbb73f291224d70bfff75a5da7bdb24165c6d6a 100644 (file)
@@ -346,11 +346,17 @@ func init() {
                {name: "MOVWloadshiftLL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1<<auxInt. arg2=mem
                {name: "MOVWloadshiftRL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, unsigned shift. arg2=mem
                {name: "MOVWloadshiftRA", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32"}, // load from arg0 + arg1>>auxInt, signed shift. arg2=mem
+               {name: "MOVBUloadidx", argLength: 3, reg: gp2load, asm: "MOVBU"},                 // load from arg0 + arg1. arg2=mem
+               {name: "MOVBloadidx", argLength: 3, reg: gp2load, asm: "MOVB"},                   // load from arg0 + arg1. arg2=mem
+               {name: "MOVHUloadidx", argLength: 3, reg: gp2load, asm: "MOVHU"},                 // load from arg0 + arg1. arg2=mem
+               {name: "MOVHloadidx", argLength: 3, reg: gp2load, asm: "MOVH"},                   // load from arg0 + arg1. arg2=mem
 
                {name: "MOVWstoreidx", argLength: 4, reg: gp2store, asm: "MOVW"},                   // store arg2 to arg0 + arg1. arg3=mem
                {name: "MOVWstoreshiftLL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1<<auxInt. arg3=mem
                {name: "MOVWstoreshiftRL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, unsigned shift. arg3=mem
                {name: "MOVWstoreshiftRA", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32"}, // store arg2 to arg0 + arg1>>auxInt, signed shift. arg3=mem
+               {name: "MOVBstoreidx", argLength: 4, reg: gp2store, asm: "MOVB"},                   // store arg2 to arg0 + arg1. arg3=mem
+               {name: "MOVHstoreidx", argLength: 4, reg: gp2store, asm: "MOVH"},                   // store arg2 to arg0 + arg1. arg3=mem
 
                {name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVBS"},  // move from arg0, sign-extended from byte
                {name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
index 6739c86ad2dacdfa69b6d962c73d2c60acf070fa..bf6149591d3aa3549c8780228711bf3efda47dcc 100644 (file)
@@ -847,10 +847,16 @@ const (
        OpARMMOVWloadshiftLL
        OpARMMOVWloadshiftRL
        OpARMMOVWloadshiftRA
+       OpARMMOVBUloadidx
+       OpARMMOVBloadidx
+       OpARMMOVHUloadidx
+       OpARMMOVHloadidx
        OpARMMOVWstoreidx
        OpARMMOVWstoreshiftLL
        OpARMMOVWstoreshiftRL
        OpARMMOVWstoreshiftRA
+       OpARMMOVBstoreidx
+       OpARMMOVHstoreidx
        OpARMMOVBreg
        OpARMMOVBUreg
        OpARMMOVHreg
@@ -10651,6 +10657,62 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "MOVBUloadidx",
+               argLen: 3,
+               asm:    arm.AMOVBU,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+                       },
+                       outputs: []outputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "MOVBloadidx",
+               argLen: 3,
+               asm:    arm.AMOVB,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+                       },
+                       outputs: []outputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "MOVHUloadidx",
+               argLen: 3,
+               asm:    arm.AMOVHU,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+                       },
+                       outputs: []outputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
+       {
+               name:   "MOVHloadidx",
+               argLen: 3,
+               asm:    arm.AMOVH,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+                       },
+                       outputs: []outputInfo{
+                               {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+                       },
+               },
+       },
        {
                name:   "MOVWstoreidx",
                argLen: 4,
@@ -10702,6 +10764,30 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "MOVBstoreidx",
+               argLen: 4,
+               asm:    arm.AMOVB,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {2, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+                       },
+               },
+       },
+       {
+               name:   "MOVHstoreidx",
+               argLen: 4,
+               asm:    arm.AMOVH,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {1, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {2, 22527},      // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 R14
+                               {0, 4294998015}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 g R12 SP R14 SB
+                       },
+               },
+       },
        {
                name:   "MOVBreg",
                argLen: 1,
index b1efbd2c0dd41b784fd3241e7ba5b2eeb414c6fa..095f8c135667d2706b5f2457fd0cc0edd6253ad7 100644 (file)
@@ -137,14 +137,20 @@ func rewriteValueARM(v *Value) bool {
                return rewriteValueARM_OpARMLessThanU_0(v)
        case OpARMMOVBUload:
                return rewriteValueARM_OpARMMOVBUload_0(v)
+       case OpARMMOVBUloadidx:
+               return rewriteValueARM_OpARMMOVBUloadidx_0(v)
        case OpARMMOVBUreg:
                return rewriteValueARM_OpARMMOVBUreg_0(v)
        case OpARMMOVBload:
                return rewriteValueARM_OpARMMOVBload_0(v)
+       case OpARMMOVBloadidx:
+               return rewriteValueARM_OpARMMOVBloadidx_0(v)
        case OpARMMOVBreg:
                return rewriteValueARM_OpARMMOVBreg_0(v)
        case OpARMMOVBstore:
                return rewriteValueARM_OpARMMOVBstore_0(v)
+       case OpARMMOVBstoreidx:
+               return rewriteValueARM_OpARMMOVBstoreidx_0(v)
        case OpARMMOVDload:
                return rewriteValueARM_OpARMMOVDload_0(v)
        case OpARMMOVDstore:
@@ -155,14 +161,20 @@ func rewriteValueARM(v *Value) bool {
                return rewriteValueARM_OpARMMOVFstore_0(v)
        case OpARMMOVHUload:
                return rewriteValueARM_OpARMMOVHUload_0(v)
+       case OpARMMOVHUloadidx:
+               return rewriteValueARM_OpARMMOVHUloadidx_0(v)
        case OpARMMOVHUreg:
                return rewriteValueARM_OpARMMOVHUreg_0(v)
        case OpARMMOVHload:
                return rewriteValueARM_OpARMMOVHload_0(v)
+       case OpARMMOVHloadidx:
+               return rewriteValueARM_OpARMMOVHloadidx_0(v)
        case OpARMMOVHreg:
                return rewriteValueARM_OpARMMOVHreg_0(v)
        case OpARMMOVHstore:
                return rewriteValueARM_OpARMMOVHstore_0(v)
+       case OpARMMOVHstoreidx:
+               return rewriteValueARM_OpARMMOVHstoreidx_0(v)
        case OpARMMOVWload:
                return rewriteValueARM_OpARMMOVWload_0(v)
        case OpARMMOVWloadidx:
@@ -5755,6 +5767,10 @@ func rewriteValueARM_OpARMLessThanU_0(v *Value) bool {
        return false
 }
 func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
        // match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
        // result: (MOVBUload [off1+off2] {sym} ptr mem)
@@ -5846,6 +5862,95 @@ func rewriteValueARM_OpARMMOVBUload_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (MOVBUload [0] {sym} (ADD ptr idx) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVBUloadidx ptr idx mem)
+       for {
+               if v.AuxInt != 0 {
+                       break
+               }
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADD {
+                       break
+               }
+               _ = v_0.Args[1]
+               ptr := v_0.Args[0]
+               idx := v_0.Args[1]
+               mem := v.Args[1]
+               if !(sym == nil && !config.nacl) {
+                       break
+               }
+               v.reset(OpARMMOVBUloadidx)
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVBUloadidx_0(v *Value) bool {
+       // match: (MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _))
+       // cond: isSamePtr(ptr, ptr2)
+       // result: (MOVBUreg x)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               idx := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVBstoreidx {
+                       break
+               }
+               _ = v_2.Args[3]
+               ptr2 := v_2.Args[0]
+               if idx != v_2.Args[1] {
+                       break
+               }
+               x := v_2.Args[2]
+               if !(isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpARMMOVBUreg)
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVBUloadidx ptr (MOVWconst [c]) mem)
+       // cond:
+       // result: (MOVBUload [c] ptr mem)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               mem := v.Args[2]
+               v.reset(OpARMMOVBUload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVBUloadidx (MOVWconst [c]) ptr mem)
+       // cond:
+       // result: (MOVBUload [c] ptr mem)
+       for {
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               ptr := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBUload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool {
@@ -5905,6 +6010,10 @@ func rewriteValueARM_OpARMMOVBUreg_0(v *Value) bool {
        return false
 }
 func rewriteValueARM_OpARMMOVBload_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
        // match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
        // result: (MOVBload [off1+off2] {sym} ptr mem)
@@ -5996,6 +6105,95 @@ func rewriteValueARM_OpARMMOVBload_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (MOVBload [0] {sym} (ADD ptr idx) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVBloadidx ptr idx mem)
+       for {
+               if v.AuxInt != 0 {
+                       break
+               }
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADD {
+                       break
+               }
+               _ = v_0.Args[1]
+               ptr := v_0.Args[0]
+               idx := v_0.Args[1]
+               mem := v.Args[1]
+               if !(sym == nil && !config.nacl) {
+                       break
+               }
+               v.reset(OpARMMOVBloadidx)
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVBloadidx_0(v *Value) bool {
+       // match: (MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _))
+       // cond: isSamePtr(ptr, ptr2)
+       // result: (MOVBreg x)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               idx := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVBstoreidx {
+                       break
+               }
+               _ = v_2.Args[3]
+               ptr2 := v_2.Args[0]
+               if idx != v_2.Args[1] {
+                       break
+               }
+               x := v_2.Args[2]
+               if !(isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpARMMOVBreg)
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVBloadidx ptr (MOVWconst [c]) mem)
+       // cond:
+       // result: (MOVBload [c] ptr mem)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               mem := v.Args[2]
+               v.reset(OpARMMOVBload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVBloadidx (MOVWconst [c]) ptr mem)
+       // cond:
+       // result: (MOVBload [c] ptr mem)
+       for {
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               ptr := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVBload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool {
@@ -6058,6 +6256,10 @@ func rewriteValueARM_OpARMMOVBreg_0(v *Value) bool {
        return false
 }
 func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
        // match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
        // cond:
        // result: (MOVBstore [off1+off2] {sym} ptr val mem)
@@ -6219,6 +6421,77 @@ func rewriteValueARM_OpARMMOVBstore_0(v *Value) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVBstore [0] {sym} (ADD ptr idx) val mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVBstoreidx ptr idx val mem)
+       for {
+               if v.AuxInt != 0 {
+                       break
+               }
+               sym := v.Aux
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADD {
+                       break
+               }
+               _ = v_0.Args[1]
+               ptr := v_0.Args[0]
+               idx := v_0.Args[1]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(sym == nil && !config.nacl) {
+                       break
+               }
+               v.reset(OpARMMOVBstoreidx)
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVBstoreidx_0(v *Value) bool {
+       // match: (MOVBstoreidx ptr (MOVWconst [c]) val mem)
+       // cond:
+       // result: (MOVBstore [c] ptr val mem)
+       for {
+               _ = v.Args[3]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               val := v.Args[2]
+               mem := v.Args[3]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVBstoreidx (MOVWconst [c]) ptr val mem)
+       // cond:
+       // result: (MOVBstore [c] ptr val mem)
+       for {
+               _ = v.Args[3]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               ptr := v.Args[1]
+               val := v.Args[2]
+               mem := v.Args[3]
+               v.reset(OpARMMOVBstore)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValueARM_OpARMMOVDload_0(v *Value) bool {
@@ -6564,6 +6837,10 @@ func rewriteValueARM_OpARMMOVFstore_0(v *Value) bool {
        return false
 }
 func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
        // match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
        // result: (MOVHUload [off1+off2] {sym} ptr mem)
@@ -6655,6 +6932,95 @@ func rewriteValueARM_OpARMMOVHUload_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (MOVHUload [0] {sym} (ADD ptr idx) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVHUloadidx ptr idx mem)
+       for {
+               if v.AuxInt != 0 {
+                       break
+               }
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADD {
+                       break
+               }
+               _ = v_0.Args[1]
+               ptr := v_0.Args[0]
+               idx := v_0.Args[1]
+               mem := v.Args[1]
+               if !(sym == nil && !config.nacl) {
+                       break
+               }
+               v.reset(OpARMMOVHUloadidx)
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVHUloadidx_0(v *Value) bool {
+       // match: (MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _))
+       // cond: isSamePtr(ptr, ptr2)
+       // result: (MOVHUreg x)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               idx := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVHstoreidx {
+                       break
+               }
+               _ = v_2.Args[3]
+               ptr2 := v_2.Args[0]
+               if idx != v_2.Args[1] {
+                       break
+               }
+               x := v_2.Args[2]
+               if !(isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpARMMOVHUreg)
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVHUloadidx ptr (MOVWconst [c]) mem)
+       // cond:
+       // result: (MOVHUload [c] ptr mem)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               mem := v.Args[2]
+               v.reset(OpARMMOVHUload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVHUloadidx (MOVWconst [c]) ptr mem)
+       // cond:
+       // result: (MOVHUload [c] ptr mem)
+       for {
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               ptr := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVHUload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool {
@@ -6739,6 +7105,10 @@ func rewriteValueARM_OpARMMOVHUreg_0(v *Value) bool {
        return false
 }
 func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
        // match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
        // cond:
        // result: (MOVHload [off1+off2] {sym} ptr mem)
@@ -6830,6 +7200,95 @@ func rewriteValueARM_OpARMMOVHload_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (MOVHload [0] {sym} (ADD ptr idx) mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVHloadidx ptr idx mem)
+       for {
+               if v.AuxInt != 0 {
+                       break
+               }
+               sym := v.Aux
+               _ = v.Args[1]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADD {
+                       break
+               }
+               _ = v_0.Args[1]
+               ptr := v_0.Args[0]
+               idx := v_0.Args[1]
+               mem := v.Args[1]
+               if !(sym == nil && !config.nacl) {
+                       break
+               }
+               v.reset(OpARMMOVHloadidx)
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVHloadidx_0(v *Value) bool {
+       // match: (MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _))
+       // cond: isSamePtr(ptr, ptr2)
+       // result: (MOVHreg x)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               idx := v.Args[1]
+               v_2 := v.Args[2]
+               if v_2.Op != OpARMMOVHstoreidx {
+                       break
+               }
+               _ = v_2.Args[3]
+               ptr2 := v_2.Args[0]
+               if idx != v_2.Args[1] {
+                       break
+               }
+               x := v_2.Args[2]
+               if !(isSamePtr(ptr, ptr2)) {
+                       break
+               }
+               v.reset(OpARMMOVHreg)
+               v.AddArg(x)
+               return true
+       }
+       // match: (MOVHloadidx ptr (MOVWconst [c]) mem)
+       // cond:
+       // result: (MOVHload [c] ptr mem)
+       for {
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               mem := v.Args[2]
+               v.reset(OpARMMOVHload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVHloadidx (MOVWconst [c]) ptr mem)
+       // cond:
+       // result: (MOVHload [c] ptr mem)
+       for {
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               ptr := v.Args[1]
+               mem := v.Args[2]
+               v.reset(OpARMMOVHload)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
@@ -6942,6 +7401,10 @@ func rewriteValueARM_OpARMMOVHreg_0(v *Value) bool {
        return false
 }
 func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool {
+       b := v.Block
+       _ = b
+       config := b.Func.Config
+       _ = config
        // match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
        // cond:
        // result: (MOVHstore [off1+off2] {sym} ptr val mem)
@@ -7059,6 +7522,77 @@ func rewriteValueARM_OpARMMOVHstore_0(v *Value) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVHstore [0] {sym} (ADD ptr idx) val mem)
+       // cond: sym == nil && !config.nacl
+       // result: (MOVHstoreidx ptr idx val mem)
+       for {
+               if v.AuxInt != 0 {
+                       break
+               }
+               sym := v.Aux
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMADD {
+                       break
+               }
+               _ = v_0.Args[1]
+               ptr := v_0.Args[0]
+               idx := v_0.Args[1]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(sym == nil && !config.nacl) {
+                       break
+               }
+               v.reset(OpARMMOVHstoreidx)
+               v.AddArg(ptr)
+               v.AddArg(idx)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpARMMOVHstoreidx_0(v *Value) bool {
+       // match: (MOVHstoreidx ptr (MOVWconst [c]) val mem)
+       // cond:
+       // result: (MOVHstore [c] ptr val mem)
+       for {
+               _ = v.Args[3]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_1.AuxInt
+               val := v.Args[2]
+               mem := v.Args[3]
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVHstoreidx (MOVWconst [c]) ptr val mem)
+       // cond:
+       // result: (MOVHstore [c] ptr val mem)
+       for {
+               _ = v.Args[3]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0.AuxInt
+               ptr := v.Args[1]
+               val := v.Args[2]
+               mem := v.Args[3]
+               v.reset(OpARMMOVHstore)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
        return false
 }
 func rewriteValueARM_OpARMMOVWload_0(v *Value) bool {