np->n_repl->n_jumps++;
if (!(np->n_flags&NUMSCAN)) {
np->n_flags |= NUMSCAN;
- reach(np->n_line->l_next);
+ if (np->n_line) {
+ 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);
+ }
}
}
}
*/
np = lnp->l_a.la_np;
if ((lnp->l_instr&BMASK) != op_lab)
- np = np->n_repl;
+ lnp->l_a.la_np = np = np->n_repl;
np->n_flags |= NUMREACH;
if (!(np->n_flags&NUMSCAN)) {
np->n_flags |= NUMSCAN;
- reach(np->n_line->l_next);
+ if (np->n_line)
+ 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)
return;
} else
superfluous = FALSE;
if ( (!reachable) || superfluous) {
+ if (instr == op_lab) {
+ lp->l_a.la_np->n_line = 0;
+ }
lp = lp->l_next;
oldline(*lpp);
OPTIM(O_UNREACH);
hashpatterns();
phashed=TRUE;
}
- optimize();
+ return optimize();
}
optimize() {
register num_p *npp,np;
register instr;
+ bool madeopt;
- basicblock(&instrs);
+ madeopt = basicblock(&instrs);
for (npp=curpro.numhash;npp< &curpro.numhash[NNUMHASH]; npp++)
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)
continue;
instr = np->n_line->l_next->l_instr&BMASK;
if (instr == op_lab || instr == op_bra)
np->n_repl = np->n_line->l_next->l_a.la_np;
else
- basicblock(&np->n_line->l_next);
+ if (basicblock(&np->n_line->l_next))
+ madeopt = TRUE;
}
+ return madeopt;
}
offset oabs(off) offset off; {
return(tryrepl(lpp,bp,patlen));
}
+int
basicblock(alpp) line_p *alpp; {
register line_p *lpp,lp;
- bool madeopt;
unsigned short hash[3];
line_p *next;
register byte *bp;
int i;
short index;
- int npasses;
+ bool madeopt;
- npasses = 0;
- do { /* make pass over basicblock */
- lpp = alpp; madeopt = FALSE;
- while ((*lpp) != (line_p) 0 && ((*lpp)->l_instr&BMASK) != op_lab) {
+ lpp = alpp; madeopt = FALSE;
+ while ((*lpp) != (line_p) 0 && ((*lpp)->l_instr&BMASK) != op_lab) {
lp = *lpp; next = &lp->l_next;
hash[0] = lp->l_instr&BMASK;
lp=lp->l_next;
}
}
lpp = next;
- }
- } while(madeopt && ++npasses<5000); /* as long as there is progress */
- assert(!madeopt);
+ }
+ return madeopt;
}
symvalue(); /* give symbols value */
if (prodepth != 0) {
if (!nflag) {
- checklocs(); /* check definition of locals */
- peephole(); /* local optimization */
+ int npasses = 0;
+ bool madeopt;
+
+ checklocs(); /* check definition of locals */
+ do {
+ madeopt = peephole(); /* local optimization */
relabel(); /* relabel local labels */
flow(); /* throw away unreachable code */
+ } while (madeopt && ++npasses < 5000);
+ assert(!madeopt);
}
outpro(); /* generate PRO pseudo */
outregs(); /* generate MES ms_reg pseudos */
for (npp = curpro.numhash; npp < &curpro.numhash[NNUMHASH]; npp++)
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
&& np->n_line->l_a.la_np == np);
for(tp=np; (tp->n_flags&(NUMKNOWN|NUMMARK))==0;
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() {
optim(n) {
fprintf(stderr,"Made optimization %d",n);
- if (inpro)
+ if (prodepth)
fprintf(stderr," (%.*s)",IDL,curpro.symbol->s_name);
fprintf(stderr,"\n");
}