diff --git a/util/opt/flow.c b/util/opt/flow.c index c5633567d..4821dff8d 100644 --- a/util/opt/flow.c +++ b/util/opt/flow.c @@ -37,7 +37,15 @@ findreach() { 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); + } } } } @@ -52,11 +60,21 @@ reach(lnp) register line_p lnp; { */ 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; @@ -99,6 +117,9 @@ cleaninstrs() { } 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); diff --git a/util/opt/peephole.c b/util/opt/peephole.c index d14ce6bc2..7c206f776 100644 --- a/util/opt/peephole.c +++ b/util/opt/peephole.c @@ -127,24 +127,28 @@ peephole() { 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; { @@ -590,20 +594,18 @@ int len; 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; @@ -638,7 +640,6 @@ basicblock(alpp) line_p *alpp; { } } lpp = next; - } - } while(madeopt && ++npasses<5000); /* as long as there is progress */ - assert(!madeopt); + } + return madeopt; } diff --git a/util/opt/process.c b/util/opt/process.c index 4545b9925..60827d795 100644 --- a/util/opt/process.c +++ b/util/opt/process.c @@ -30,10 +30,16 @@ process() { 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 */ @@ -62,6 +68,7 @@ relabel() { 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; @@ -75,6 +82,11 @@ relabel() { 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() { diff --git a/util/opt/util.c b/util/opt/util.c index a6835cbd4..da9e3b8ac 100644 --- a/util/opt/util.c +++ b/util/opt/util.c @@ -44,7 +44,7 @@ badassertion(file,line) char *file; unsigned line; { optim(n) { fprintf(stderr,"Made optimization %d",n); - if (inpro) + if (prodepth) fprintf(stderr," (%.*s)",IDL,curpro.symbol->s_name); fprintf(stderr,"\n"); }