]> Cypherpunks repositories - gostls13.git/commitdiff
8g: optimize byte mov
authorRuss Cox <rsc@golang.org>
Fri, 8 Apr 2011 17:53:59 +0000 (13:53 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 8 Apr 2011 17:53:59 +0000 (13:53 -0400)
Rewrite MOVB with less expensive
instruction when possible.

Suggested by atomic symbol.

benchmark                                        old ns/op    new ns/op    delta
crc32.BenchmarkCrc32KB                               13066         3942  -69.83%
crc64.BenchmarkCrc64KB                                8780         5949  -32.24%
lzw.BenchmarkDecoder1e4                             771224       636538  -17.46%
lzw.BenchmarkDecoder1e5                            7101218      6096634  -14.15%
lzw.BenchmarkDecoder1e6                           69762020     60789400  -12.86%
lzw.BenchmarkEncoder1e4                             707968       638812   -9.77%
lzw.BenchmarkEncoder1e5                            6567122      5965552   -9.16%
lzw.BenchmarkEncoder1e6                           65006000     58911680   -9.38%
utf8_test.BenchmarkRuneCountTenASCIIChars              166          165   -0.60%
utf8_test.BenchmarkRuneCountTenJapaneseChars           246          258   +4.88%
utf8_test.BenchmarkEncodeASCIIRune                      13           10  -23.08%
utf8_test.BenchmarkEncodeJapaneseRune                   37           16  -56.76%
utf8_test.BenchmarkDecodeASCIIRune                      23           21   -8.70%
utf8_test.BenchmarkDecodeJapaneseRune                   58           32  -44.83%

R=ken2
CC=golang-dev
https://golang.org/cl/4381045

src/cmd/8g/peep.c

index 580b1a922325f426f96ba1e335902a581fa77d8d..5ad29e1b219b8d307f987bc0094e1a92d3cbd1a8 100644 (file)
@@ -120,6 +120,25 @@ peep(void)
                        p = p->link;
                }
        }
+       
+       // movb elimination.
+       // movb is simulated by the linker
+       // when a register other than ax, bx, cx, dx
+       // is used, so rewrite to other instructions
+       // when possible.  a movb into a register
+       // can smash the entire 32-bit register without
+       // causing any trouble.
+       for(r=firstr; r!=R; r=r->link) {
+               p = r->prog;
+               if(p->as == AMOVB && regtyp(&p->to)) {
+                       // movb into register.
+                       // from another register or constant can be movl.
+                       if(regtyp(&p->from) || p->from.type == D_CONST)
+                               p->as = AMOVL;
+                       else
+                               p->as = AMOVBLZX;
+               }
+       }
 
        // constant propagation
        // find MOV $con,R followed by
@@ -152,6 +171,8 @@ loop1:
        for(r=firstr; r!=R; r=r->link) {
                p = r->prog;
                switch(p->as) {
+               case AMOVB:
+               case AMOVW:
                case AMOVL:
                        if(regtyp(&p->to))
                        if(regtyp(&p->from)) {
@@ -182,6 +203,7 @@ loop1:
                        }
                        break;
 
+               case AADDB:
                case AADDL:
                case AADDW:
                        if(p->from.type != D_CONST || needc(p->link))
@@ -204,6 +226,7 @@ loop1:
                        }
                        break;
 
+               case ASUBB:
                case ASUBL:
                case ASUBW:
                        if(p->from.type != D_CONST || needc(p->link))
@@ -380,6 +403,8 @@ subprop(Reg *r0)
                case AMOVSL:
                        return 0;
 
+               case AMOVB:
+               case AMOVW:
                case AMOVL:
                        if(p->to.type == v1->type)
                                goto gotit;
@@ -560,6 +585,8 @@ copyu(Prog *p, Adr *v, Adr *s)
 
 
        case ANOP:      /* rhs store */
+       case AMOVB:
+       case AMOVW:
        case AMOVL:
        case AMOVBLSX:
        case AMOVBLZX:
@@ -624,8 +651,6 @@ copyu(Prog *p, Adr *v, Adr *s)
        case AXORB:
        case AXORL:
        case AXORW:
-       case AMOVB:
-       case AMOVW:
                if(copyas(&p->to, v))
                        return 2;
                goto caseread;