1
0
mirror of https://github.com/golang/go synced 2024-11-24 12:30:14 -07:00

8g: optimize byte mov

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
This commit is contained in:
Russ Cox 2011-04-08 13:53:59 -04:00
parent e7c4a6dfca
commit 23f6479be6

View File

@ -120,6 +120,25 @@ peep(void)
p = p->link; 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 // constant propagation
// find MOV $con,R followed by // find MOV $con,R followed by
@ -152,6 +171,8 @@ loop1:
for(r=firstr; r!=R; r=r->link) { for(r=firstr; r!=R; r=r->link) {
p = r->prog; p = r->prog;
switch(p->as) { switch(p->as) {
case AMOVB:
case AMOVW:
case AMOVL: case AMOVL:
if(regtyp(&p->to)) if(regtyp(&p->to))
if(regtyp(&p->from)) { if(regtyp(&p->from)) {
@ -182,6 +203,7 @@ loop1:
} }
break; break;
case AADDB:
case AADDL: case AADDL:
case AADDW: case AADDW:
if(p->from.type != D_CONST || needc(p->link)) if(p->from.type != D_CONST || needc(p->link))
@ -204,6 +226,7 @@ loop1:
} }
break; break;
case ASUBB:
case ASUBL: case ASUBL:
case ASUBW: case ASUBW:
if(p->from.type != D_CONST || needc(p->link)) if(p->from.type != D_CONST || needc(p->link))
@ -380,6 +403,8 @@ subprop(Reg *r0)
case AMOVSL: case AMOVSL:
return 0; return 0;
case AMOVB:
case AMOVW:
case AMOVL: case AMOVL:
if(p->to.type == v1->type) if(p->to.type == v1->type)
goto gotit; goto gotit;
@ -560,6 +585,8 @@ copyu(Prog *p, Adr *v, Adr *s)
case ANOP: /* rhs store */ case ANOP: /* rhs store */
case AMOVB:
case AMOVW:
case AMOVL: case AMOVL:
case AMOVBLSX: case AMOVBLSX:
case AMOVBLZX: case AMOVBLZX:
@ -624,8 +651,6 @@ copyu(Prog *p, Adr *v, Adr *s)
case AXORB: case AXORB:
case AXORL: case AXORL:
case AXORW: case AXORW:
case AMOVB:
case AMOVW:
if(copyas(&p->to, v)) if(copyas(&p->to, v))
return 2; return 2;
goto caseread; goto caseread;