]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm64: simplify ADD and SUB
authorBen Shi <powerman1st@163.com>
Tue, 11 Sep 2018 08:55:10 +0000 (08:55 +0000)
committerCherry Zhang <cherryyz@google.com>
Thu, 4 Oct 2018 20:26:13 +0000 (20:26 +0000)
Currently "ADD $0x123456, Rs, Rd" will load pre-stored 0x123456
from the constant pool and use it for the addition. Total 12 bytes
are cost. And so does SUB.

This CL breaks it to "ADD 0x123000, Rs, Rd" + "ADD 0x000456, Rd, Rd".
Both "0x123000" and "0x000456" can be directly encoded into the
instruction binary code. So 4 bytes are saved.

1. The total size of pkg/android_arm64 decreases about 0.3KB.

2. The go1 benchmark show little regression (excluding noise).

name                     old time/op    new time/op    delta
BinaryTree17-4              15.9s ± 0%     15.9s ± 1%  +0.10%  (p=0.044 n=29+29)
Fannkuch11-4                8.72s ± 0%     8.75s ± 0%  +0.34%  (p=0.000 n=30+24)
FmtFprintfEmpty-4           173ns ± 0%     173ns ± 0%    ~     (all equal)
FmtFprintfString-4          368ns ± 0%     368ns ± 0%    ~     (p=0.593 n=30+30)
FmtFprintfInt-4             417ns ± 0%     417ns ± 0%    ~     (all equal)
FmtFprintfIntInt-4          673ns ± 0%     661ns ± 1%  -1.70%  (p=0.000 n=30+30)
FmtFprintfPrefixedInt-4     805ns ± 0%     805ns ± 0%  +0.10%  (p=0.011 n=30+30)
FmtFprintfFloat-4          1.09µs ± 0%    1.09µs ± 0%    ~     (p=0.125 n=30+29)
FmtManyArgs-4              2.68µs ± 0%    2.68µs ± 0%  +0.07%  (p=0.004 n=30+30)
GobDecode-4                32.9ms ± 0%    33.2ms ± 1%  +1.07%  (p=0.000 n=29+29)
GobEncode-4                29.5ms ± 0%    29.6ms ± 0%  +0.26%  (p=0.000 n=28+28)
Gzip-4                      1.38s ± 1%     1.35s ± 3%  -1.94%  (p=0.000 n=28+30)
Gunzip-4                    139ms ± 0%     139ms ± 0%  +0.10%  (p=0.000 n=28+29)
HTTPClientServer-4          745µs ± 5%     742µs ± 3%    ~     (p=0.405 n=28+29)
JSONEncode-4               49.5ms ± 1%    49.9ms ± 0%  +0.89%  (p=0.000 n=30+30)
JSONDecode-4                264ms ± 1%     264ms ± 0%  +0.25%  (p=0.001 n=30+30)
Mandelbrot200-4            16.6ms ± 0%    16.6ms ± 0%    ~     (p=0.507 n=29+29)
GoParse-4                  15.9ms ± 0%    16.0ms ± 1%  +0.91%  (p=0.002 n=23+30)
RegexpMatchEasy0_32-4       379ns ± 0%     379ns ± 0%    ~     (all equal)
RegexpMatchEasy0_1K-4      1.31µs ± 0%    1.31µs ± 0%  +0.09%  (p=0.008 n=27+30)
RegexpMatchEasy1_32-4       357ns ± 0%     358ns ± 0%  +0.28%  (p=0.000 n=28+29)
RegexpMatchEasy1_1K-4      2.04µs ± 0%    2.04µs ± 0%    ~     (p=0.850 n=30+30)
RegexpMatchMedium_32-4      587ns ± 0%     589ns ± 0%  +0.33%  (p=0.000 n=30+30)
RegexpMatchMedium_1K-4      162µs ± 0%     163µs ± 0%    ~     (p=0.351 n=30+29)
RegexpMatchHard_32-4       9.54µs ± 0%    9.60µs ± 0%  +0.59%  (p=0.000 n=28+30)
RegexpMatchHard_1K-4        287µs ± 0%     287µs ± 0%  +0.11%  (p=0.000 n=26+29)
Revcomp-4                   2.50s ± 0%     2.50s ± 0%  -0.13%  (p=0.012 n=28+27)
Template-4                  312ms ± 1%     312ms ± 1%  +0.20%  (p=0.015 n=27+30)
TimeParse-4                1.68µs ± 0%    1.68µs ± 0%  -0.35%  (p=0.000 n=30+30)
TimeFormat-4               1.66µs ± 0%    1.64µs ± 0%  -1.20%  (p=0.000 n=25+29)
[Geo mean]                  246µs          246µs       -0.00%

name                     old speed      new speed      delta
GobDecode-4              23.3MB/s ± 0%  23.1MB/s ± 1%  -1.05%  (p=0.000 n=29+29)
GobEncode-4              26.0MB/s ± 0%  25.9MB/s ± 0%  -0.25%  (p=0.000 n=29+28)
Gzip-4                   14.1MB/s ± 1%  14.4MB/s ± 3%  +1.94%  (p=0.000 n=27+30)
Gunzip-4                  139MB/s ± 0%   139MB/s ± 0%  -0.10%  (p=0.000 n=28+29)
JSONEncode-4             39.2MB/s ± 1%  38.9MB/s ± 0%  -0.88%  (p=0.000 n=30+30)
JSONDecode-4             7.37MB/s ± 0%  7.35MB/s ± 0%  -0.26%  (p=0.001 n=30+30)
GoParse-4                3.65MB/s ± 0%  3.62MB/s ± 1%  -0.86%  (p=0.001 n=23+30)
RegexpMatchEasy0_32-4    84.3MB/s ± 0%  84.3MB/s ± 0%    ~     (p=0.126 n=27+26)
RegexpMatchEasy0_1K-4     784MB/s ± 0%   783MB/s ± 0%  -0.10%  (p=0.003 n=27+30)
RegexpMatchEasy1_32-4    89.5MB/s ± 0%  89.3MB/s ± 0%  -0.20%  (p=0.000 n=27+29)
RegexpMatchEasy1_1K-4     502MB/s ± 0%   502MB/s ± 0%    ~     (p=0.858 n=30+28)
RegexpMatchMedium_32-4   1.70MB/s ± 0%  1.70MB/s ± 0%  -0.25%  (p=0.000 n=30+30)
RegexpMatchMedium_1K-4   6.30MB/s ± 0%  6.30MB/s ± 0%    ~     (all equal)
RegexpMatchHard_32-4     3.35MB/s ± 0%  3.33MB/s ± 0%  -0.47%  (p=0.000 n=30+30)
RegexpMatchHard_1K-4     3.57MB/s ± 0%  3.56MB/s ± 0%  -0.20%  (p=0.000 n=27+30)
Revcomp-4                 102MB/s ± 0%   102MB/s ± 0%  +0.14%  (p=0.008 n=28+28)
Template-4               6.23MB/s ± 0%  6.21MB/s ± 1%  -0.21%  (p=0.009 n=21+30)
[Geo mean]               24.1MB/s       24.0MB/s       -0.16%

Change-Id: Ifcef3edb667540e2d86e586c23afcfbc2cf1340b
Reviewed-on: https://go-review.googlesource.com/c/134536
Run-TryBot: Ben Shi <powerman1st@163.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/asm/internal/asm/testdata/arm64.s
src/cmd/internal/obj/arm64/a.out.go
src/cmd/internal/obj/arm64/anames7.go
src/cmd/internal/obj/arm64/asm7.go

index 9e2e2b1dc5436ac872e9549433efce9f9e888b01..079c620f9be8c17b5ff01d51589cb1d0939d4439 100644 (file)
@@ -25,6 +25,18 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
        ADD     R1, R2, R3
        ADD     R1, ZR, R3
        ADD     $1, R2, R3
+       ADD     $0x000aaa, R2, R3 // ADD $2730, R2, R3     // 43a82a91
+       ADD     $0x000aaa, R2     // ADD $2730, R2         // 42a82a91
+       ADD     $0xaaa000, R2, R3 // ADD $11182080, R2, R3 // 43a86a91
+       ADD     $0xaaa000, R2     // ADD $11182080, R2     // 42a86a91
+       ADD     $0xaaaaaa, R2, R3 // ADD $11184810, R2, R3 // 43a82a9163a86a91
+       ADD     $0xaaaaaa, R2     // ADD $11184810, R2     // 42a82a9142a86a91
+       SUB     $0x000aaa, R2, R3 // SUB $2730, R2, R3     // 43a82ad1
+       SUB     $0x000aaa, R2     // SUB $2730, R2         // 42a82ad1
+       SUB     $0xaaa000, R2, R3 // SUB $11182080, R2, R3 // 43a86ad1
+       SUB     $0xaaa000, R2     // SUB $11182080, R2     // 42a86ad1
+       SUB     $0xaaaaaa, R2, R3 // SUB $11184810, R2, R3 // 43a82ad163a86ad1
+       SUB     $0xaaaaaa, R2     // SUB $11184810, R2     // 42a82ad142a86ad1
        ADD     R1>>11, R2, R3
        ADD     R1<<22, R2, R3
        ADD     R1->33, R2, R3
index 65647c37ae70e2c6523a1142e6bed75bed8be583..37df688b21a6994a9aa27c61c009cc9383ceb0d5 100644 (file)
@@ -411,6 +411,7 @@ const (
        C_MBCON    // could be C_MOVCON or C_BITCON
        C_MOVCON   // generated by a 16-bit constant, optionally inverted and/or shifted by multiple of 16
        C_BITCON   // bitfield and logical immediate masks
+       C_ADDCON2  // 24-bit constant
        C_LCON     // 32-bit constant
        C_VCON     // 64-bit constant
        C_FCON     // floating-point constant
index 92f0cec94271b17aa6336e4992d0a38a95d4b462..a768f2cbefdd338cec4fdc93d01bd1682ce06be1 100644 (file)
@@ -27,6 +27,7 @@ var cnames7 = []string{
        "MBCON",
        "MOVCON",
        "BITCON",
+       "ADDCON2",
        "LCON",
        "VCON",
        "FCON",
index 46fdcdcf7dff55a127c37748eb4b9195d6e00b98..67cefe3aeb613610e3e6bf60d1e5ab6e17df26a9 100644 (file)
@@ -192,6 +192,8 @@ var optab = []Optab{
        {AADD, C_BITCON, C_RSP, C_NONE, C_RSP, 62, 8, 0, 0, 0},
        {AADD, C_BITCON, C_NONE, C_NONE, C_RSP, 62, 8, 0, 0, 0},
        {ACMP, C_BITCON, C_RSP, C_NONE, C_NONE, 62, 8, 0, 0, 0},
+       {AADD, C_ADDCON2, C_RSP, C_NONE, C_RSP, 48, 8, 0, 0, 0},
+       {AADD, C_ADDCON2, C_NONE, C_NONE, C_RSP, 48, 8, 0, 0, 0},
        {AADD, C_VCON, C_RSP, C_NONE, C_RSP, 13, 8, 0, LFROM, 0},
        {AADD, C_VCON, C_NONE, C_NONE, C_RSP, 13, 8, 0, LFROM, 0},
        {ACMP, C_VCON, C_REG, C_NONE, C_NONE, 13, 8, 0, LFROM, 0},
@@ -1046,6 +1048,7 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
                C_NOREG4K,
                C_LOREG,
                C_LACON,
+               C_ADDCON2,
                C_LCON,
                C_VCON:
                if a.Name == obj.NAME_EXTERN {
@@ -1537,6 +1540,10 @@ func (c *ctxt7) aclass(a *obj.Addr) int {
                                return C_BITCON
                        }
 
+                       if 0 <= v && v <= 0xffffff {
+                               return C_ADDCON2
+                       }
+
                        if uint64(v) == uint64(uint32(v)) || v == int64(int32(v)) {
                                return C_LCON
                        }
@@ -1595,7 +1602,12 @@ func (c *ctxt7) oplook(p *obj.Prog) *Optab {
        }
        a1 = int(p.From.Class)
        if a1 == 0 {
-               a1 = c.aclass(&p.From) + 1
+               a0 := c.aclass(&p.From)
+               // do not break C_ADDCON2 when S bit is set
+               if (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) && a0 == C_ADDCON2 {
+                       a0 = C_LCON
+               }
+               a1 = a0 + 1
                p.From.Class = int8(a1)
        }
 
@@ -1681,8 +1693,13 @@ func cmp(a int, b int) bool {
                        return true
                }
 
+       case C_ADDCON2:
+               if b == C_ZCON || b == C_ADDCON || b == C_ADDCON0 {
+                       return true
+               }
+
        case C_LCON:
-               if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON {
+               if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON || b == C_ADDCON2 {
                        return true
                }
 
@@ -3474,6 +3491,19 @@ func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
                }
                o1 |= 0x1c1<<21 | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
 
+       case 48: /* ADD $C_ADDCON2, Rm, Rd */
+               op := c.opirr(p, p.As)
+               if op&Sbit != 0 {
+                       c.ctxt.Diag("can not break addition/subtraction when S bit is set", p)
+               }
+               rt := int(p.To.Reg)
+               r := int(p.Reg)
+               if r == 0 {
+                       r = rt
+               }
+               o1 = c.oaddi(p, int32(op), int32(c.regoff(&p.From)) & 0x000fff, r, rt)
+               o2 = c.oaddi(p, int32(op), int32(c.regoff(&p.From)) & 0xfff000, rt, rt)
+
        case 50: /* sys/sysl */
                o1 = c.opirr(p, p.As)