Improved label handling and handling of jumps to jumps

This commit is contained in:
ceriel 1989-02-06 14:39:08 +00:00
parent e0c7813927
commit 929716a621
4 changed files with 52 additions and 18 deletions

View file

@ -37,7 +37,15 @@ findreach() {
np->n_repl->n_jumps++; np->n_repl->n_jumps++;
if (!(np->n_flags&NUMSCAN)) { if (!(np->n_flags&NUMSCAN)) {
np->n_flags |= NUMSCAN; np->n_flags |= NUMSCAN;
if (np->n_line) {
reach(np->n_line->l_next); reach(np->n_line->l_next);
continue;
}
if (!(np->n_repl->n_flags&NUMSCAN)) {
np->n_repl->n_flags |= NUMSCAN;
if (np->n_repl->n_line)
reach(np->n_repl->n_line->l_next);
}
} }
} }
} }
@ -52,11 +60,21 @@ reach(lnp) register line_p lnp; {
*/ */
np = lnp->l_a.la_np; np = lnp->l_a.la_np;
if ((lnp->l_instr&BMASK) != op_lab) if ((lnp->l_instr&BMASK) != op_lab)
np = np->n_repl; lnp->l_a.la_np = np = np->n_repl;
np->n_flags |= NUMREACH; np->n_flags |= NUMREACH;
if (!(np->n_flags&NUMSCAN)) { if (!(np->n_flags&NUMSCAN)) {
np->n_flags |= NUMSCAN; np->n_flags |= NUMSCAN;
if (np->n_line)
reach(np->n_line->l_next); reach(np->n_line->l_next);
else {
np = np->n_repl;
np->n_flags |= NUMREACH;
if (!(np->n_flags & NUMSCAN)) {
np->n_flags |= NUMSCAN;
if (np->n_line)
reach(np->n_line->l_next);
}
}
} }
if ((lnp->l_instr&BMASK) == op_lab) if ((lnp->l_instr&BMASK) == op_lab)
return; return;
@ -99,6 +117,9 @@ cleaninstrs() {
} else } else
superfluous = FALSE; superfluous = FALSE;
if ( (!reachable) || superfluous) { if ( (!reachable) || superfluous) {
if (instr == op_lab) {
lp->l_a.la_np->n_line = 0;
}
lp = lp->l_next; lp = lp->l_next;
oldline(*lpp); oldline(*lpp);
OPTIM(O_UNREACH); OPTIM(O_UNREACH);

View file

@ -127,24 +127,28 @@ peephole() {
hashpatterns(); hashpatterns();
phashed=TRUE; phashed=TRUE;
} }
optimize(); return optimize();
} }
optimize() { optimize() {
register num_p *npp,np; register num_p *npp,np;
register instr; register instr;
bool madeopt;
basicblock(&instrs); madeopt = basicblock(&instrs);
for (npp=curpro.numhash;npp< &curpro.numhash[NNUMHASH]; npp++) for (npp=curpro.numhash;npp< &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np=np->n_next) { for (np = *npp; np != (num_p) 0; np=np->n_next) {
if (! np->n_line) continue;
if(np->n_line->l_next == (line_p) 0) if(np->n_line->l_next == (line_p) 0)
continue; continue;
instr = np->n_line->l_next->l_instr&BMASK; instr = np->n_line->l_next->l_instr&BMASK;
if (instr == op_lab || instr == op_bra) if (instr == op_lab || instr == op_bra)
np->n_repl = np->n_line->l_next->l_a.la_np; np->n_repl = np->n_line->l_next->l_a.la_np;
else else
basicblock(&np->n_line->l_next); if (basicblock(&np->n_line->l_next))
madeopt = TRUE;
} }
return madeopt;
} }
offset oabs(off) offset off; { offset oabs(off) offset off; {
@ -590,18 +594,16 @@ int len;
return(tryrepl(lpp,bp,patlen)); return(tryrepl(lpp,bp,patlen));
} }
int
basicblock(alpp) line_p *alpp; { basicblock(alpp) line_p *alpp; {
register line_p *lpp,lp; register line_p *lpp,lp;
bool madeopt;
unsigned short hash[3]; unsigned short hash[3];
line_p *next; line_p *next;
register byte *bp; register byte *bp;
int i; int i;
short index; short index;
int npasses; bool madeopt;
npasses = 0;
do { /* make pass over basicblock */
lpp = alpp; madeopt = FALSE; lpp = alpp; madeopt = FALSE;
while ((*lpp) != (line_p) 0 && ((*lpp)->l_instr&BMASK) != op_lab) { while ((*lpp) != (line_p) 0 && ((*lpp)->l_instr&BMASK) != op_lab) {
lp = *lpp; next = &lp->l_next; lp = *lpp; next = &lp->l_next;
@ -639,6 +641,5 @@ basicblock(alpp) line_p *alpp; {
} }
lpp = next; lpp = next;
} }
} while(madeopt && ++npasses<5000); /* as long as there is progress */ return madeopt;
assert(!madeopt);
} }

View file

@ -30,10 +30,16 @@ process() {
symvalue(); /* give symbols value */ symvalue(); /* give symbols value */
if (prodepth != 0) { if (prodepth != 0) {
if (!nflag) { if (!nflag) {
int npasses = 0;
bool madeopt;
checklocs(); /* check definition of locals */ checklocs(); /* check definition of locals */
peephole(); /* local optimization */ do {
madeopt = peephole(); /* local optimization */
relabel(); /* relabel local labels */ relabel(); /* relabel local labels */
flow(); /* throw away unreachable code */ flow(); /* throw away unreachable code */
} while (madeopt && ++npasses < 5000);
assert(!madeopt);
} }
outpro(); /* generate PRO pseudo */ outpro(); /* generate PRO pseudo */
outregs(); /* generate MES ms_reg pseudos */ outregs(); /* generate MES ms_reg pseudos */
@ -62,6 +68,7 @@ relabel() {
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++) for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np = np->n_next) { for (np = *npp; np != (num_p) 0; np = np->n_next) {
if (! np->n_line) continue;
assert((np->n_line->l_instr&BMASK) == op_lab assert((np->n_line->l_instr&BMASK) == op_lab
&& np->n_line->l_a.la_np == np); && np->n_line->l_a.la_np == np);
for(tp=np; (tp->n_flags&(NUMKNOWN|NUMMARK))==0; for(tp=np; (tp->n_flags&(NUMKNOWN|NUMMARK))==0;
@ -75,6 +82,11 @@ relabel() {
tp->n_flags |= NUMKNOWN; tp->n_flags |= NUMKNOWN;
} }
} }
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
for (np = *npp; np != (num_p) 0; np = np->n_next) {
np->n_flags &= ~(NUMKNOWN|NUMSCAN|NUMREACH);
np->n_jumps = 0;
}
} }
symknown() { symknown() {

View file

@ -44,7 +44,7 @@ badassertion(file,line) char *file; unsigned line; {
optim(n) { optim(n) {
fprintf(stderr,"Made optimization %d",n); fprintf(stderr,"Made optimization %d",n);
if (inpro) if (prodepth)
fprintf(stderr," (%.*s)",IDL,curpro.symbol->s_name); fprintf(stderr," (%.*s)",IDL,curpro.symbol->s_name);
fprintf(stderr,"\n"); fprintf(stderr,"\n");
} }