mirror of
https://github.com/golang/go
synced 2024-11-12 07:40:23 -07:00
reg and peep
R=r OCL=19871 CL=19871
This commit is contained in:
parent
5169bb44e6
commit
e081f25c3e
@ -176,12 +176,14 @@ cgen(Node *n, Node *res)
|
||||
gins(optoas(OCMP, types[tptr]), &n1, &n2);
|
||||
p1 = gbranch(optoas(OEQ, types[tptr]), T);
|
||||
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[TINT32];
|
||||
gmove(&n1, res);
|
||||
n2 = n1;
|
||||
n2.op = OINDREG;
|
||||
n2.type = types[TINT32];
|
||||
gmove(&n2, &n1);
|
||||
|
||||
patch(p1, pc);
|
||||
|
||||
gmove(&n1, res);
|
||||
regfree(&n1);
|
||||
break;
|
||||
}
|
||||
|
@ -100,9 +100,8 @@ if(throwreturn == N) {
|
||||
pc->as = ARET; // overwrite AEND
|
||||
pc->lineno = lineno;
|
||||
|
||||
if(debug['N']) {
|
||||
if(!debug['N'] || debug['R'] || debug['P'])
|
||||
regopt(ptxt);
|
||||
}
|
||||
|
||||
// fill in argument size
|
||||
ptxt->to.offset = rnd(curfn->type->argwid, maxround);
|
||||
@ -918,6 +917,33 @@ cgen_asop(Node *n)
|
||||
nl = n->left;
|
||||
nr = n->right;
|
||||
|
||||
if(nl->addable && nr->op == OLITERAL)
|
||||
switch(n->etype) {
|
||||
case OADD:
|
||||
if(!isint[nl->type->etype])
|
||||
goto com;
|
||||
if(mpgetfix(nr->val.u.xval) != 1)
|
||||
goto com;
|
||||
gins(optoas(OINC, nl->type), N, nl);
|
||||
goto ret;
|
||||
case OSUB:
|
||||
if(!isint[nl->type->etype])
|
||||
goto com;
|
||||
if(mpgetfix(nr->val.u.xval) != 1)
|
||||
goto com;
|
||||
gins(optoas(ODEC, nl->type), N, nl);
|
||||
goto ret;
|
||||
|
||||
com:
|
||||
case OXOR:
|
||||
case OAND:
|
||||
case OOR:
|
||||
if(!isint[nl->type->etype])
|
||||
break;
|
||||
gins(optoas(n->etype, nl->type), nr, nl);
|
||||
goto ret;
|
||||
}
|
||||
|
||||
if(nr->ullman >= UINF && nl->ullman >= UINF) {
|
||||
tempname(&n1, nr->type);
|
||||
cgen(nr, &n1);
|
||||
@ -960,10 +986,12 @@ cgen_as(Node *nl, Node *nr, int op)
|
||||
Node nc, n1;
|
||||
Type *tl;
|
||||
uint32 w, c;
|
||||
int iszer;
|
||||
|
||||
if(nl == N)
|
||||
return;
|
||||
|
||||
iszer = 0;
|
||||
if(nr == N || isnil(nr)) {
|
||||
if(nl->op == OLIST) {
|
||||
cgen_as(nl->left, nr, op);
|
||||
@ -1008,6 +1036,7 @@ cgen_as(Node *nl, Node *nr, int op)
|
||||
}
|
||||
|
||||
/* invent a "zero" for the rhs */
|
||||
iszer = 1;
|
||||
nr = &nc;
|
||||
memset(nr, 0, sizeof(*nr));
|
||||
switch(tl->etype) {
|
||||
@ -1062,6 +1091,9 @@ cgen_as(Node *nl, Node *nr, int op)
|
||||
return;
|
||||
|
||||
cgen(nr, nl);
|
||||
if(iszer && nl->addable)
|
||||
gins(ANOP, nl, N); // used
|
||||
|
||||
|
||||
ret:
|
||||
;
|
||||
|
@ -383,7 +383,7 @@ gmove(Node *f, Node *t)
|
||||
case TPTR32:
|
||||
a = AMOVL;
|
||||
if(t64)
|
||||
a = AMOVLQZX; /* could probably use plain MOVL */
|
||||
a = AMOVLQZX;
|
||||
goto ld;
|
||||
case TINT64:
|
||||
if(isfloat[tt]) {
|
||||
@ -480,50 +480,50 @@ gmove(Node *f, Node *t)
|
||||
/*
|
||||
* integer to integer
|
||||
********
|
||||
a = AGOK; break;
|
||||
* a = AGOK; break;
|
||||
|
||||
case CASE(TBOOL, TBOOL):
|
||||
case CASE(TINT8, TBOOL):
|
||||
case CASE(TUINT8, TBOOL):
|
||||
case CASE(TINT16, TBOOL):
|
||||
case CASE(TUINT16, TBOOL):
|
||||
case CASE(TINT32, TBOOL):
|
||||
case CASE(TUINT32, TBOOL):
|
||||
case CASE(TPTR64, TBOOL):
|
||||
* case CASE(TBOOL, TBOOL):
|
||||
* case CASE(TINT8, TBOOL):
|
||||
* case CASE(TUINT8, TBOOL):
|
||||
* case CASE(TINT16, TBOOL):
|
||||
* case CASE(TUINT16, TBOOL):
|
||||
* case CASE(TINT32, TBOOL):
|
||||
* case CASE(TUINT32, TBOOL):
|
||||
* case CASE(TPTR64, TBOOL):
|
||||
|
||||
case CASE(TBOOL, TINT8):
|
||||
case CASE(TINT8, TINT8):
|
||||
case CASE(TUINT8, TINT8):
|
||||
case CASE(TINT16, TINT8):
|
||||
case CASE(TUINT16, TINT8):
|
||||
case CASE(TINT32, TINT8):
|
||||
case CASE(TUINT32, TINT8):
|
||||
case CASE(TPTR64, TINT8):
|
||||
* case CASE(TBOOL, TINT8):
|
||||
* case CASE(TINT8, TINT8):
|
||||
* case CASE(TUINT8, TINT8):
|
||||
* case CASE(TINT16, TINT8):
|
||||
* case CASE(TUINT16, TINT8):
|
||||
* case CASE(TINT32, TINT8):
|
||||
* case CASE(TUINT32, TINT8):
|
||||
* case CASE(TPTR64, TINT8):
|
||||
|
||||
case CASE(TBOOL, TUINT8):
|
||||
case CASE(TINT8, TUINT8):
|
||||
case CASE(TUINT8, TUINT8):
|
||||
case CASE(TINT16, TUINT8):
|
||||
case CASE(TUINT16, TUINT8):
|
||||
case CASE(TINT32, TUINT8):
|
||||
case CASE(TUINT32, TUINT8):
|
||||
case CASE(TPTR64, TUINT8):
|
||||
* case CASE(TBOOL, TUINT8):
|
||||
* case CASE(TINT8, TUINT8):
|
||||
* case CASE(TUINT8, TUINT8):
|
||||
* case CASE(TINT16, TUINT8):
|
||||
* case CASE(TUINT16, TUINT8):
|
||||
* case CASE(TINT32, TUINT8):
|
||||
* case CASE(TUINT32, TUINT8):
|
||||
* case CASE(TPTR64, TUINT8):
|
||||
|
||||
case CASE(TINT16, TINT16):
|
||||
case CASE(TUINT16, TINT16):
|
||||
case CASE(TINT32, TINT16):
|
||||
case CASE(TUINT32, TINT16):
|
||||
case CASE(TPTR64, TINT16):
|
||||
* case CASE(TINT16, TINT16):
|
||||
* case CASE(TUINT16, TINT16):
|
||||
* case CASE(TINT32, TINT16):
|
||||
* case CASE(TUINT32, TINT16):
|
||||
* case CASE(TPTR64, TINT16):
|
||||
|
||||
case CASE(TINT16, TUINT16):
|
||||
case CASE(TUINT16, TUINT16):
|
||||
case CASE(TINT32, TUINT16):
|
||||
case CASE(TUINT32, TUINT16):
|
||||
case CASE(TPTR64, TUINT16):
|
||||
* case CASE(TINT16, TUINT16):
|
||||
* case CASE(TUINT16, TUINT16):
|
||||
* case CASE(TINT32, TUINT16):
|
||||
* case CASE(TUINT32, TUINT16):
|
||||
* case CASE(TPTR64, TUINT16):
|
||||
|
||||
case CASE(TINT64, TUINT):
|
||||
case CASE(TINT64, TUINT32):
|
||||
case CASE(TUINT64, TUINT32):
|
||||
* case CASE(TINT64, TUINT):
|
||||
* case CASE(TINT64, TUINT32):
|
||||
* case CASE(TUINT64, TUINT32):
|
||||
*****/
|
||||
a = AMOVL;
|
||||
break;
|
||||
@ -534,25 +534,21 @@ gmove(Node *f, Node *t)
|
||||
case CASE(TUINT64, TINT8):
|
||||
case CASE(TUINT64, TINT16):
|
||||
case CASE(TUINT64, TINT32):
|
||||
a = AMOVLQSX; // this looks bad
|
||||
break;
|
||||
|
||||
case CASE(TINT32, TINT64):
|
||||
case CASE(TINT32, TPTR64):
|
||||
a = AMOVLQSX;
|
||||
// if(f->op == OCONST) {
|
||||
// f->val.vval &= (uvlong)0xffffffffU;
|
||||
// if(f->val.vval & 0x80000000)
|
||||
// f->val.vval |= (vlong)0xffffffff << 32;
|
||||
// a = AMOVQ;
|
||||
// }
|
||||
break;
|
||||
|
||||
case CASE(TUINT32, TINT64):
|
||||
case CASE(TUINT32, TUINT64):
|
||||
case CASE(TUINT32, TPTR64):
|
||||
a = AMOVL; /* same effect as AMOVLQZX */
|
||||
// if(f->op == OCONST) {
|
||||
// f->val.vval &= (uvlong)0xffffffffU;
|
||||
// a = AMOVQ;
|
||||
// }
|
||||
case CASE(TPTR32, TINT64):
|
||||
case CASE(TPTR32, TUINT64):
|
||||
case CASE(TPTR32, TPTR64):
|
||||
a = AMOVLQZX;
|
||||
break;
|
||||
|
||||
case CASE(TPTR64, TINT64):
|
||||
@ -1239,6 +1235,50 @@ optoas(int op, Type *t)
|
||||
a = ASUBSD;
|
||||
break;
|
||||
|
||||
case CASE(OINC, TINT8):
|
||||
case CASE(OINC, TUINT8):
|
||||
a = AINCB;
|
||||
break;
|
||||
|
||||
case CASE(OINC, TINT16):
|
||||
case CASE(OINC, TUINT16):
|
||||
a = AINCW;
|
||||
break;
|
||||
|
||||
case CASE(OINC, TINT32):
|
||||
case CASE(OINC, TUINT32):
|
||||
case CASE(OINC, TPTR32):
|
||||
a = AINCL;
|
||||
break;
|
||||
|
||||
case CASE(OINC, TINT64):
|
||||
case CASE(OINC, TUINT64):
|
||||
case CASE(OINC, TPTR64):
|
||||
a = AINCQ;
|
||||
break;
|
||||
|
||||
case CASE(ODEC, TINT8):
|
||||
case CASE(ODEC, TUINT8):
|
||||
a = ADECB;
|
||||
break;
|
||||
|
||||
case CASE(ODEC, TINT16):
|
||||
case CASE(ODEC, TUINT16):
|
||||
a = ADECW;
|
||||
break;
|
||||
|
||||
case CASE(ODEC, TINT32):
|
||||
case CASE(ODEC, TUINT32):
|
||||
case CASE(ODEC, TPTR32):
|
||||
a = ADECL;
|
||||
break;
|
||||
|
||||
case CASE(ODEC, TINT64):
|
||||
case CASE(ODEC, TUINT64):
|
||||
case CASE(ODEC, TPTR64):
|
||||
a = ADECQ;
|
||||
break;
|
||||
|
||||
case CASE(OMINUS, TINT8):
|
||||
case CASE(OMINUS, TUINT8):
|
||||
a = ANEGB;
|
||||
|
@ -60,7 +60,6 @@ struct Bits
|
||||
uint32 b[BITS];
|
||||
};
|
||||
|
||||
|
||||
struct Reg
|
||||
{
|
||||
|
||||
@ -75,14 +74,12 @@ struct Reg
|
||||
Bits regdiff;
|
||||
Bits act;
|
||||
|
||||
int32 regu;
|
||||
int32 loop; /* could be shorter */
|
||||
int32 rpo; /* reverse post ordering */
|
||||
int32 regu; // register used bitmap
|
||||
int32 rpo; // reverse post ordering
|
||||
int32 active;
|
||||
|
||||
// uint32 magic;
|
||||
// int32 pc;
|
||||
// Reg* log5;
|
||||
uint16 loop; // x5 for every loop
|
||||
uchar refset; // diagnostic generated
|
||||
|
||||
Reg* p1;
|
||||
Reg* p2;
|
||||
@ -130,10 +127,9 @@ EXTERN Bits externs;
|
||||
EXTERN Bits params;
|
||||
EXTERN Bits consts;
|
||||
EXTERN Bits addrs;
|
||||
EXTERN Bits ovar;
|
||||
EXTERN int change;
|
||||
EXTERN Bits zbits;
|
||||
EXTERN uchar typechlpfd[NTYPE]; // botch
|
||||
EXTERN uchar typev[NTYPE]; // botch
|
||||
EXTERN int32 maxnr;
|
||||
EXTERN int32* idom;
|
||||
|
||||
@ -150,6 +146,15 @@ int beq(Bits, Bits);
|
||||
int bset(Bits, uint);
|
||||
int Qconv(Fmt *fp);
|
||||
int bitno(int32);
|
||||
struct
|
||||
{
|
||||
int32 ncvtreg;
|
||||
int32 nspill;
|
||||
int32 nreload;
|
||||
int32 ndelmov;
|
||||
int32 nvar;
|
||||
int32 naddr;
|
||||
} ostats;
|
||||
|
||||
/*
|
||||
* reg.c
|
||||
@ -167,6 +172,8 @@ void paint1(Reg*, int);
|
||||
uint32 paint2(Reg*, int);
|
||||
void paint3(Reg*, int, int32, int);
|
||||
void addreg(Adr*, int);
|
||||
void dumpit(char *str, Reg *r0);
|
||||
int noreturn(Prog *p);
|
||||
|
||||
/*
|
||||
* peep.c
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "gg.h"
|
||||
#include "opt.h"
|
||||
|
||||
|
||||
static int
|
||||
needc(Prog *p)
|
||||
{
|
||||
@ -67,7 +68,7 @@ rnops(Reg *r)
|
||||
Reg *r1;
|
||||
|
||||
if(r != R)
|
||||
for(;;){
|
||||
for(;;) {
|
||||
p = r->prog;
|
||||
if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
|
||||
break;
|
||||
@ -103,6 +104,8 @@ peep(void)
|
||||
r2->link = r1;
|
||||
|
||||
r2->prog = p;
|
||||
p->reg = r2;
|
||||
|
||||
r2->p1 = r;
|
||||
r->s1 = r2;
|
||||
r2->s1 = r1;
|
||||
@ -119,10 +122,11 @@ peep(void)
|
||||
}
|
||||
}
|
||||
|
||||
pc = 0; /* speculating it won't kill */
|
||||
|
||||
loop1:
|
||||
|
||||
if(debug['P'] && debug['v'])
|
||||
dumpit("loop1", firstr);
|
||||
|
||||
t = 0;
|
||||
for(r=firstr; r!=R; r=r->link) {
|
||||
p = r->prog;
|
||||
@ -186,13 +190,15 @@ loop1:
|
||||
if(p->from.offset == -1){
|
||||
if(p->as == AADDQ)
|
||||
p->as = ADECQ;
|
||||
else if(p->as == AADDL)
|
||||
else
|
||||
if(p->as == AADDL)
|
||||
p->as = ADECL;
|
||||
else
|
||||
p->as = ADECW;
|
||||
p->from = zprog.from;
|
||||
}
|
||||
else if(p->from.offset == 1){
|
||||
else
|
||||
if(p->from.offset == 1){
|
||||
if(p->as == AADDQ)
|
||||
p->as = AINCQ;
|
||||
else if(p->as == AADDL)
|
||||
@ -211,16 +217,19 @@ loop1:
|
||||
if(p->from.offset == -1) {
|
||||
if(p->as == ASUBQ)
|
||||
p->as = AINCQ;
|
||||
else if(p->as == ASUBL)
|
||||
else
|
||||
if(p->as == ASUBL)
|
||||
p->as = AINCL;
|
||||
else
|
||||
p->as = AINCW;
|
||||
p->from = zprog.from;
|
||||
}
|
||||
else if(p->from.offset == 1){
|
||||
else
|
||||
if(p->from.offset == 1){
|
||||
if(p->as == ASUBQ)
|
||||
p->as = ADECQ;
|
||||
else if(p->as == ASUBL)
|
||||
else
|
||||
if(p->as == ASUBL)
|
||||
p->as = ADECL;
|
||||
else
|
||||
p->as = ADECW;
|
||||
@ -239,9 +248,14 @@ excise(Reg *r)
|
||||
Prog *p;
|
||||
|
||||
p = r->prog;
|
||||
if(debug['P'] && debug['v'])
|
||||
print("%P ===delete===\n", p);
|
||||
|
||||
p->as = ANOP;
|
||||
p->from = zprog.from;
|
||||
p->to = zprog.to;
|
||||
|
||||
ostats.ndelmov++;
|
||||
}
|
||||
|
||||
Reg*
|
||||
|
181
src/cmd/6g/reg.c
181
src/cmd/6g/reg.c
@ -34,11 +34,8 @@
|
||||
#include "opt.h"
|
||||
|
||||
#define P2R(p) (Reg*)(p->reg)
|
||||
#define MAGIC 0xb00fbabe
|
||||
|
||||
static int first = 1;
|
||||
static void dumpit(char *str, Reg *r0);
|
||||
static int noreturn(Prog *p);
|
||||
|
||||
Reg*
|
||||
rega(void)
|
||||
@ -70,6 +67,30 @@ rcmp(const void *a1, const void *a2)
|
||||
return p2->varno - p1->varno;
|
||||
}
|
||||
|
||||
void
|
||||
setoutvar(void)
|
||||
{
|
||||
Type *t;
|
||||
Node *n;
|
||||
Addr a;
|
||||
Iter save;
|
||||
Bits bit;
|
||||
int z;
|
||||
|
||||
t = structfirst(&save, getoutarg(curfn->type));
|
||||
while(t != T) {
|
||||
n = nodarg(t, 1);
|
||||
a = zprog.from;
|
||||
naddr(n, &a);
|
||||
bit = mkvar(R, &a);
|
||||
for(z=0; z<BITS; z++)
|
||||
ovar.b[z] |= bit.b[z];
|
||||
t = structnext(&save);
|
||||
}
|
||||
//if(bany(b))
|
||||
//print("ovars = %Q\n", &ovar);
|
||||
}
|
||||
|
||||
void
|
||||
regopt(Prog *firstp)
|
||||
{
|
||||
@ -93,8 +114,12 @@ regopt(Prog *firstp)
|
||||
params.b[z] = 0;
|
||||
consts.b[z] = 0;
|
||||
addrs.b[z] = 0;
|
||||
ovar.b[z] = 0;
|
||||
}
|
||||
|
||||
// build list of return variables
|
||||
setoutvar();
|
||||
|
||||
/*
|
||||
* pass 1
|
||||
* build aux data structure
|
||||
@ -221,6 +246,15 @@ regopt(Prog *firstp)
|
||||
/*
|
||||
* right side read+write
|
||||
*/
|
||||
case AINCB:
|
||||
case AINCL:
|
||||
case AINCQ:
|
||||
case AINCW:
|
||||
case ADECB:
|
||||
case ADECL:
|
||||
case ADECQ:
|
||||
case ADECW:
|
||||
|
||||
case AADDB:
|
||||
case AADDL:
|
||||
case AADDQ:
|
||||
@ -380,7 +414,9 @@ regopt(Prog *firstp)
|
||||
}
|
||||
if(firstr == R)
|
||||
return;
|
||||
//dumpit("pass1", firstr);
|
||||
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass1", firstr);
|
||||
|
||||
/*
|
||||
* pass 2
|
||||
@ -396,7 +432,7 @@ regopt(Prog *firstp)
|
||||
if(r1 == R)
|
||||
fatal("rnil %P", p);
|
||||
if(r1 == r) {
|
||||
fatal("ref to self %P", p);
|
||||
//fatal("ref to self %P", p);
|
||||
continue;
|
||||
}
|
||||
r->s2 = r1;
|
||||
@ -404,7 +440,9 @@ regopt(Prog *firstp)
|
||||
r1->p2 = r;
|
||||
}
|
||||
}
|
||||
//dumpit("pass2", firstr);
|
||||
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass2", firstr);
|
||||
|
||||
/*
|
||||
* pass 2.5
|
||||
@ -414,7 +452,9 @@ regopt(Prog *firstp)
|
||||
r->active = 0;
|
||||
change = 0;
|
||||
loopit(firstr, nr);
|
||||
//dumpit("pass2.5", firstr);
|
||||
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass2.5", firstr);
|
||||
|
||||
/*
|
||||
* pass 3
|
||||
@ -443,7 +483,8 @@ loop11:
|
||||
if(change)
|
||||
goto loop1;
|
||||
|
||||
//dumpit("pass3", firstr);
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass3", firstr);
|
||||
|
||||
/*
|
||||
* pass 4
|
||||
@ -458,7 +499,8 @@ loop2:
|
||||
if(change)
|
||||
goto loop2;
|
||||
|
||||
//dumpit("pass4", firstr);
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass4", firstr);
|
||||
|
||||
/*
|
||||
* pass 5
|
||||
@ -470,10 +512,11 @@ loop2:
|
||||
for(z=0; z<BITS; z++)
|
||||
bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
|
||||
~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
|
||||
if(bany(&bit)) {
|
||||
warn("used and not set: %Q", bit);
|
||||
if(debug['R'] && !debug['w'])
|
||||
print("used and not set: %Q\n", bit);
|
||||
if(bany(&bit) && !r->refset) {
|
||||
// should never happen - all variables are preset
|
||||
if(debug['w'])
|
||||
print("%L: used and not set: %Q\n", r->prog->lineno, bit);
|
||||
r->refset = 1;
|
||||
}
|
||||
}
|
||||
for(r = firstr; r != R; r = r->link)
|
||||
@ -484,10 +527,10 @@ loop2:
|
||||
for(z=0; z<BITS; z++)
|
||||
bit.b[z] = r->set.b[z] &
|
||||
~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
|
||||
if(bany(&bit)) {
|
||||
warn("set and not used: %Q", bit);
|
||||
if(debug['R'])
|
||||
print("set and not used: %Q\n", bit);
|
||||
if(bany(&bit) && !r->refset) {
|
||||
if(debug['w'])
|
||||
print("%L: set and not used: %Q\n", r->prog->lineno, bit);
|
||||
r->refset = 1;
|
||||
excise(r);
|
||||
}
|
||||
for(z=0; z<BITS; z++)
|
||||
@ -497,20 +540,15 @@ loop2:
|
||||
rgp->enter = r;
|
||||
rgp->varno = i;
|
||||
change = 0;
|
||||
if(debug['R'] && debug['v'])
|
||||
print("\n");
|
||||
paint1(r, i);
|
||||
bit.b[i/32] &= ~(1L<<(i%32));
|
||||
if(change <= 0) {
|
||||
if(debug['R'])
|
||||
print("%L$%d: %Q\n",
|
||||
r->prog->lineno, change, blsh(i));
|
||||
if(change <= 0)
|
||||
continue;
|
||||
}
|
||||
rgp->cost = change;
|
||||
nregion++;
|
||||
if(nregion >= NRGN) {
|
||||
fatal("too many regions");
|
||||
if(debug['R'] && debug['v'])
|
||||
print("too many regions\n");
|
||||
goto brk;
|
||||
}
|
||||
rgp++;
|
||||
@ -534,11 +572,14 @@ brk:
|
||||
rgp++;
|
||||
}
|
||||
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass6", firstr);
|
||||
|
||||
/*
|
||||
* pass 7
|
||||
* peep-hole on basic block
|
||||
*/
|
||||
if(debug['P']) {
|
||||
if(!debug['R'] || debug['P']) {
|
||||
peep();
|
||||
}
|
||||
|
||||
@ -547,14 +588,43 @@ brk:
|
||||
* free aux structures
|
||||
*/
|
||||
for(p=firstp; p!=P; p=p->link) {
|
||||
while(p->link && p->link->as == ANOP)
|
||||
while(p->link != P && p->link->as == ANOP)
|
||||
p->link = p->link->link;
|
||||
if(p->to.type == D_BRANCH)
|
||||
while(p->to.branch != P && p->to.branch->as == ANOP)
|
||||
p->to.branch = p->to.branch->link;
|
||||
}
|
||||
|
||||
if(r1 != R) {
|
||||
r1->link = freer;
|
||||
freer = firstr;
|
||||
}
|
||||
|
||||
if(debug['R']) {
|
||||
if(ostats.ncvtreg ||
|
||||
ostats.nspill ||
|
||||
ostats.nreload ||
|
||||
ostats.ndelmov ||
|
||||
ostats.nvar ||
|
||||
ostats.naddr ||
|
||||
0)
|
||||
print("\nstats\n");
|
||||
|
||||
if(ostats.ncvtreg)
|
||||
print(" %4ld cvtreg\n", ostats.ncvtreg);
|
||||
if(ostats.nspill)
|
||||
print(" %4ld spill\n", ostats.nspill);
|
||||
if(ostats.nreload)
|
||||
print(" %4ld reload\n", ostats.nreload);
|
||||
if(ostats.ndelmov)
|
||||
print(" %4ld delmov\n", ostats.ndelmov);
|
||||
if(ostats.nvar)
|
||||
print(" %4ld delmov\n", ostats.nvar);
|
||||
if(ostats.naddr)
|
||||
print(" %4ld delmov\n", ostats.naddr);
|
||||
|
||||
memset(&ostats, 0, sizeof(ostats));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -585,7 +655,7 @@ addmove(Reg *r, int bn, int rn, int f)
|
||||
a->etype = v->etype;
|
||||
a->type = v->name;
|
||||
|
||||
// need to chean this up with wptr and
|
||||
// need to clean this up with wptr and
|
||||
// some of the defaults
|
||||
p1->as = AMOVL;
|
||||
switch(v->etype) {
|
||||
@ -611,7 +681,7 @@ addmove(Reg *r, int bn, int rn, int f)
|
||||
p1->as = AMOVSS;
|
||||
break;
|
||||
case TFLOAT64:
|
||||
p1->as = AMOVSS;
|
||||
p1->as = AMOVSD;
|
||||
break;
|
||||
case TINT:
|
||||
case TUINT:
|
||||
@ -631,8 +701,9 @@ addmove(Reg *r, int bn, int rn, int f)
|
||||
if(v->etype == TUINT16)
|
||||
p1->as = AMOVW;
|
||||
}
|
||||
// if(debug['R'])
|
||||
print("%P\t.a%P\n", p, p1);
|
||||
if(debug['R'] && debug['v'])
|
||||
print("%P ===add=== %P\n", p, p1);
|
||||
ostats.nspill++;
|
||||
}
|
||||
|
||||
uint32
|
||||
@ -670,8 +741,10 @@ mkvar(Reg *r, Adr *a)
|
||||
* mark registers used
|
||||
*/
|
||||
t = a->type;
|
||||
r->regu |= doregbits(t);
|
||||
r->regu |= doregbits(a->index);
|
||||
if(r != R) {
|
||||
r->regu |= doregbits(t);
|
||||
r->regu |= doregbits(a->index);
|
||||
}
|
||||
|
||||
switch(t) {
|
||||
default:
|
||||
@ -682,6 +755,7 @@ mkvar(Reg *r, Adr *a)
|
||||
for(z=0; z<BITS; z++)
|
||||
addrs.b[z] |= bit.b[z];
|
||||
a->type = t;
|
||||
ostats.naddr++;
|
||||
goto none;
|
||||
case D_EXTERN:
|
||||
case D_STATIC:
|
||||
@ -727,6 +801,7 @@ mkvar(Reg *r, Adr *a)
|
||||
v->etype = et;
|
||||
if(debug['R'])
|
||||
print("bit=%2d et=%2d %D\n", i, et, a);
|
||||
ostats.nvar++;
|
||||
|
||||
out:
|
||||
bit = blsh(i);
|
||||
@ -738,7 +813,8 @@ out:
|
||||
params.b[z] |= bit.b[z];
|
||||
if(v->etype != et) {
|
||||
/* funny punning */
|
||||
print("pun %d %d %S\n", v->etype, et, s);
|
||||
if(debug['R'])
|
||||
print("pun %d %d %S\n", v->etype, et, s);
|
||||
for(z=0; z<BITS; z++)
|
||||
addrs.b[z] |= bit.b[z];
|
||||
}
|
||||
@ -787,9 +863,10 @@ prop(Reg *r, Bits ref, Bits cal)
|
||||
|
||||
case ARET:
|
||||
for(z=0; z<BITS; z++) {
|
||||
cal.b[z] = externs.b[z];
|
||||
cal.b[z] = externs.b[z] | ovar.b[z];
|
||||
ref.b[z] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
for(z=0; z<BITS; z++) {
|
||||
ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
|
||||
@ -1044,9 +1121,6 @@ paint1(Reg *r, int bn)
|
||||
|
||||
if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
|
||||
change -= CLOAD * r->loop;
|
||||
if(debug['R'] && debug['v'])
|
||||
print("%ld%P\tld %Q $%d\n", r->loop,
|
||||
r->prog, blsh(bn), change);
|
||||
}
|
||||
for(;;) {
|
||||
r->act.b[z] |= bb;
|
||||
@ -1054,23 +1128,14 @@ paint1(Reg *r, int bn)
|
||||
|
||||
if(r->use1.b[z] & bb) {
|
||||
change += CREF * r->loop;
|
||||
if(debug['R'] && debug['v'])
|
||||
print("%ld%P\tu1 %Q $%d\n", r->loop,
|
||||
p, blsh(bn), change);
|
||||
}
|
||||
|
||||
if((r->use2.b[z]|r->set.b[z]) & bb) {
|
||||
change += CREF * r->loop;
|
||||
if(debug['R'] && debug['v'])
|
||||
print("%ld%P\tu2 %Q $%d\n", r->loop,
|
||||
p, blsh(bn), change);
|
||||
}
|
||||
|
||||
if(STORE(r) & r->regdiff.b[z] & bb) {
|
||||
change -= CLOAD * r->loop;
|
||||
if(debug['R'] && debug['v'])
|
||||
print("%ld%P\tst %Q $%d\n", r->loop,
|
||||
p, blsh(bn), change);
|
||||
}
|
||||
|
||||
if(r->refbehind.b[z] & bb)
|
||||
@ -1226,18 +1291,18 @@ paint3(Reg *r, int bn, int32 rb, int rn)
|
||||
p = r->prog;
|
||||
|
||||
if(r->use1.b[z] & bb) {
|
||||
if(debug['R'])
|
||||
if(debug['R'] && debug['v'])
|
||||
print("%P", p);
|
||||
addreg(&p->from, rn);
|
||||
if(debug['R'])
|
||||
print("\t.c%P\n", p);
|
||||
if(debug['R'] && debug['v'])
|
||||
print(" ===change== %P\n", p);
|
||||
}
|
||||
if((r->use2.b[z]|r->set.b[z]) & bb) {
|
||||
if(debug['R'])
|
||||
if(debug['R'] && debug['v'])
|
||||
print("%P", p);
|
||||
addreg(&p->to, rn);
|
||||
if(debug['R'])
|
||||
print("\t.c%P\n", p);
|
||||
if(debug['R'] && debug['v'])
|
||||
print(" ===change== %P\n", p);
|
||||
}
|
||||
|
||||
if(STORE(r) & r->regdiff.b[z] & bb)
|
||||
@ -1272,6 +1337,8 @@ addreg(Adr *a, int rn)
|
||||
a->sym = 0;
|
||||
a->offset = 0;
|
||||
a->type = rn;
|
||||
|
||||
ostats.ncvtreg++;
|
||||
}
|
||||
|
||||
int32
|
||||
@ -1286,8 +1353,7 @@ RtoB(int r)
|
||||
int
|
||||
BtoR(int32 b)
|
||||
{
|
||||
|
||||
b &= 0xffffL;
|
||||
b &= 0x3fffL; // no R14 or R15
|
||||
if(b == 0)
|
||||
return 0;
|
||||
return bitno(b) + D_AX;
|
||||
@ -1317,7 +1383,7 @@ BtoF(int32 b)
|
||||
return bitno(b) - 16 + FREGMIN;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
dumpit(char *str, Reg *r0)
|
||||
{
|
||||
Reg *r, *r1;
|
||||
@ -1380,7 +1446,7 @@ dumpit(char *str, Reg *r0)
|
||||
|
||||
static Sym* symlist[10];
|
||||
|
||||
static int
|
||||
int
|
||||
noreturn(Prog *p)
|
||||
{
|
||||
Sym *s;
|
||||
@ -1388,6 +1454,7 @@ noreturn(Prog *p)
|
||||
|
||||
if(symlist[0] == S) {
|
||||
symlist[0] = pkglookup("throwindex", "sys");
|
||||
symlist[1] = pkglookup("panicl", "sys");
|
||||
}
|
||||
|
||||
s = p->to.sym;
|
||||
|
@ -284,6 +284,7 @@ enum
|
||||
OEQ, ONE, OLT, OLE, OGE, OGT,
|
||||
OADD, OSUB, OOR, OXOR,
|
||||
OMUL, ODIV, OMOD, OLSH, ORSH, OAND,
|
||||
OINC, ODEC, // placeholders - not used
|
||||
OFUNC,
|
||||
OLABEL,
|
||||
OBREAK,
|
||||
|
@ -1094,7 +1094,20 @@ loop:
|
||||
goto ret;
|
||||
|
||||
nottop:
|
||||
yyerror("didn't expect %O here", n->op);
|
||||
switch(top) {
|
||||
default:
|
||||
yyerror("didn't expect %O here", n->op);
|
||||
break;
|
||||
case Etop:
|
||||
yyerror("operation %O not allowed in statement context", n->op);
|
||||
break;
|
||||
case Elv:
|
||||
yyerror("operation %O not allowed in assignment context", n->op);
|
||||
break;
|
||||
case Erv:
|
||||
yyerror("operation %O not allowed in expression context", n->op);
|
||||
break;
|
||||
}
|
||||
goto ret;
|
||||
|
||||
badt:
|
||||
|
Loading…
Reference in New Issue
Block a user