1
0
mirror of https://github.com/golang/go synced 2024-11-20 06:04:52 -07:00

arm optimizer bug fixes

R=rsc
CC=golang-dev
https://golang.org/cl/3913043
This commit is contained in:
Ken Thompson 2011-01-10 13:15:52 -08:00
parent 212e074be2
commit ab4d8bf16c
2 changed files with 110 additions and 80 deletions

View File

@ -37,6 +37,7 @@ int shiftprop(Reg *r);
void constprop(Adr *c1, Adr *v1, Reg *r);
void predicate(void);
int copyau1(Prog *p, Adr *v);
int isdconst(Addr *a);
void
peep(void)
@ -81,30 +82,42 @@ loop1:
t = 0;
for(r=firstr; r!=R; r=r->link) {
p = r->prog;
if(p->as == ASLL || p->as == ASRL || p->as == ASRA) {
switch(p->as) {
case ASLL:
case ASRL:
case ASRA:
/*
* elide shift into D_SHIFT operand of subsequent instruction
*/
if(shiftprop(r)) {
excise(r);
t++;
break;
}
}
if(p->as == AMOVW || p->as == AMOVF || p->as == AMOVD)
if(regtyp(&p->to)) {
if(p->from.type == D_CONST)
break;
case AMOVW:
case AMOVF:
case AMOVD:
if(!regtyp(&p->to))
break;
if(isdconst(&p->from)) {
constprop(&p->from, &p->to, r->s1);
else
if(regtyp(&p->from))
if(p->from.type == p->to.type) {
if(copyprop(r)) {
excise(r);
t++;
} else
if(subprop(r) && copyprop(r)) {
excise(r);
t++;
}
break;
}
if(!regtyp(&p->from))
break;
if(p->from.type != p->to.type)
break;
if(copyprop(r)) {
excise(r);
t++;
break;
}
if(subprop(r) && copyprop(r)) {
excise(r);
t++;
break;
}
}
}
@ -122,7 +135,7 @@ loop1:
/*
* EOR -1,x,y => MVN x,y
*/
if(p->from.type == D_CONST && p->from.offset == -1) {
if(isdconst(&p->from) && p->from.offset == -1) {
p->as = AMVN;
p->from.type = D_REG;
if(p->reg != NREG)
@ -170,7 +183,7 @@ loop1:
/*
* elide CMP $0,x if calculation of x can set condition codes
*/
if(p->from.type != D_CONST || p->from.offset != 0)
if(isdconst(&p->from) || p->from.offset != 0)
continue;
r2 = r->s1;
if(r2 == R)
@ -668,12 +681,14 @@ shiftprop(Reg *r)
}
break;
}
/* make the substitution */
p2->from.type = D_SHIFT;
p2->from.reg = NREG;
o = p->reg;
if(o == NREG)
o = p->to.reg;
switch(p->from.type){
case D_CONST:
o |= (p->from.offset&0x1f)<<7;
@ -735,7 +750,7 @@ findinc(Reg *r, Reg *r2, Adr *v)
case 4: /* set and used */
p = r1->prog;
if(p->as == AADD)
if(p->from.type == D_CONST)
if(isdconst(&p->from))
if(p->from.offset > -4096 && p->from.offset < 4096)
return r1;
default:
@ -990,7 +1005,6 @@ copyu(Prog *p, Adr *v, Adr *s)
return 1;
return 0;
case AADD: /* read, read, write */
case ASUB:
case ARSB:
@ -1192,6 +1206,10 @@ copyau(Adr *a, Adr *v)
if(copyas(a, v))
return 1;
if(v->type == D_REG) {
if(a->type == D_CONST && a->reg != NREG) {
if(v->reg == a->reg)
return 1;
} else
if(a->type == D_OREG) {
if(v->reg == a->reg)
return 1;
@ -1320,19 +1338,22 @@ isbranch(Prog *p)
int
predicable(Prog *p)
{
if (isbranch(p)
|| p->as == ANOP
|| p->as == AXXX
|| p->as == ADATA
|| p->as == AGLOBL
|| p->as == AGOK
|| p->as == AHISTORY
|| p->as == ANAME
|| p->as == ASIGNAME
|| p->as == ATEXT
|| p->as == AWORD
|| p->as == ABCASE
|| p->as == ACASE)
switch(p->as) {
case ANOP:
case AXXX:
case ADATA:
case AGLOBL:
case AGOK:
case AHISTORY:
case ANAME:
case ASIGNAME:
case ATEXT:
case AWORD:
case ABCASE:
case ACASE:
return 0;
}
if(isbranch(p))
return 0;
return 1;
}
@ -1347,18 +1368,23 @@ predicable(Prog *p)
int
modifiescpsr(Prog *p)
{
return (p->scond&C_SBIT)
|| p->as == ATST
|| p->as == ATEQ
|| p->as == ACMN
|| p->as == ACMP
|| p->as == AMULU
|| p->as == ADIVU
|| p->as == AMUL
|| p->as == ADIV
|| p->as == AMOD
|| p->as == AMODU
|| p->as == ABL;
switch(p->as) {
case ATST:
case ATEQ:
case ACMN:
case ACMP:
case AMULU:
case ADIVU:
case AMUL:
case ADIV:
case AMOD:
case AMODU:
case ABL:
return 1;
}
if(p->scond & C_SBIT)
return 1;
return 0;
}
/*
@ -1401,10 +1427,10 @@ joinsplit(Reg *r, Joininfo *j)
return Toolong;
}
Reg *
Reg*
successor(Reg *r)
{
if (r->s1)
if(r->s1)
return r->s1;
else
return r->s2;
@ -1418,23 +1444,24 @@ applypred(Reg *rstart, Joininfo *j, int cond, int branch)
if(j->len == 0)
return;
if (cond == Truecond)
if(cond == Truecond)
pred = predinfo[rstart->prog->as - ABEQ].scond;
else
pred = predinfo[rstart->prog->as - ABEQ].notscond;
for (r = j->start; ; r = successor(r)) {
for(r = j->start;; r = successor(r)) {
if (r->prog->as == AB) {
if (r != j->last || branch == Delbranch)
excise(r);
else {
if (cond == Truecond)
r->prog->as = predinfo[rstart->prog->as - ABEQ].opcode;
else
r->prog->as = predinfo[rstart->prog->as - ABEQ].notopcode;
if (cond == Truecond)
r->prog->as = predinfo[rstart->prog->as - ABEQ].opcode;
else
r->prog->as = predinfo[rstart->prog->as - ABEQ].notopcode;
}
}
else if (predicable(r->prog))
else
if (predicable(r->prog))
r->prog->scond = (r->prog->scond&~C_SCOND)|pred;
if (r->s1 != r->link) {
r->s1 = r->link;
@ -1474,3 +1501,11 @@ predicate(void)
}
}
}
int
isdconst(Addr *a)
{
if(a->type == D_CONST && a->reg == NREG)
return 1;
return 0;
}

View File

@ -102,7 +102,7 @@ excise(Reg *r)
p->scond = zprog.scond;
p->from = zprog.from;
p->to = zprog.to;
p->reg = zprog.reg; /**/
p->reg = zprog.reg;
}
static void
@ -139,22 +139,16 @@ regopt(Prog *firstp)
if(first == 0) {
fmtinstall('Q', Qconv);
// exregoffset = D_R13; // R14,R15 are external
}
first++;
//if(!debug['K'])
// return;
//if(first != 19) {
// return;
//}
//print("optimizing %S\n", curfn->nname->sym);
//debug['R'] = 2;
//debug['P'] = 2;
if(debug['K']) {
if(first != 20)
return;
// debug['R'] = 2;
// debug['P'] = 2;
print("optimizing %S\n", curfn->nname->sym);
}
// count instructions
nr = 0;
@ -189,7 +183,6 @@ regopt(Prog *firstp)
* allocate pcs
* find use and set of variables
*/
if(0) print("pass 1\n");
nr = 0;
for(p=firstp; p != P; p = p->link) {
switch(p->as) {
@ -284,7 +277,6 @@ if(0) print("pass 1\n");
* turn branch references to pointers
* build back pointers
*/
if(0) print("pass 2\n");
for(r=firstr; r!=R; r=r->link) {
p = r->prog;
if(p->to.type == D_BRANCH) {
@ -311,7 +303,6 @@ if(0) print("pass 2\n");
* pass 2.5
* find looping structure
*/
if(0) print("pass 2.5\n");
for(r = firstr; r != R; r = r->link)
r->active = 0;
change = 0;
@ -323,7 +314,6 @@ if(0) print("pass 2.5\n");
* back until flow graph is complete
*/
loop1:
if(0) print("loop 1\n");
change = 0;
for(r = firstr; r != R; r = r->link)
r->active = 0;
@ -331,7 +321,6 @@ if(0) print("loop 1\n");
if(r->prog->as == ARET)
prop(r, zbits, zbits);
loop11:
if(0) print("loop 11\n");
/* pick up unreachable code */
i = 0;
for(r = firstr; r != R; r = r1) {
@ -353,7 +342,6 @@ if(0) print("loop 11\n");
* forward until graph is complete
*/
loop2:
if(0) print("loop 2\n");
change = 0;
for(r = firstr; r != R; r = r->link)
r->active = 0;
@ -400,7 +388,6 @@ if(0) print("loop 2\n");
* isolate regions
* calculate costs (paint1)
*/
if(0) print("pass 5\n");
r = firstr;
if(r) {
for(z=0; z<BITS; z++)
@ -490,7 +477,6 @@ brk:
* pass 7
* peep-hole on basic block
*/
if(0) print("pass 7\n");
if(!debug['R'] || debug['P']) {
peep();
}
@ -652,8 +638,12 @@ mkvar(Reg *r, Adr *a, int docon)
print("type %d %d %D\n", t, a->name, a);
goto none;
case D_NONE:
case D_CONST:
if(a->reg != NREG)
r->regu |= RtoB(a->reg);
// fallthrough
case D_NONE:
case D_FCONST:
case D_BRANCH:
goto none;
@ -1028,9 +1018,6 @@ allreg(uint32 b, Rgn *r)
}
break;
case TINT64:
case TUINT64:
case TPTR64:
case TFLOAT32:
case TFLOAT64:
case TFLOAT:
@ -1040,6 +1027,14 @@ allreg(uint32 b, Rgn *r)
return FtoB(i);
}
break;
case TINT64:
case TUINT64:
case TPTR64:
case TINTER:
case TSTRUCT:
case TARRAY:
break;
}
return 0;
}