optcse.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 947 行 · 第 1/2 页
C
947 行
{ case TYSHORT: case TYLONG: if(ap->ci == bp->ci) return(TRUE); break; case TYREAL: case TYDREAL: if(ap->cd[0] == bp->cd[0]) return(TRUE); break; case TYCOMPLEX: case TYDCOMPLEX: if(ap->cd[0] == bp->cd[0] && ap->cd[1] == bp->cd[1] ) return(TRUE); break; } } break; default : badtag ("samebase",ep2->tag); } return(FALSE);}LOCAL idptr findid(idaddr)expptr idaddr;/* Find an identifier's IDblock given its idaddr. If the identifier has no** IBblock build one*/{ register idptr idp; if(current_BB->headid == 0) newid(idaddr,¤t_BB->headid); idp=current_BB->headid; do { if (samebase(idp->idaddr,idaddr) ) break; if (idp->next == 0) { newid(idaddr,&idp->next); idp = idp->next; break; } idp = idp->next; } while(TRUE); return(idp);}LOCAL valuen findnode(ep,leftc,rightc)expptr ep;valuen leftc,rightc;{ /* Look for a matching value node in the available computations stack */ register valuen p; for ( p=current_BB->headnode; p ; p=p->next) { if( ( ! p->is_dead) && (p->lc == leftc) && (p->rc == rightc) && ( (ep->tag == TEXPR && p->opp->tag == TEXPR && p->opp->exprblock.opcode == ep->exprblock.opcode && p->opp->exprblock.vtype == ep->exprblock.vtype ) || (ep->tag == TADDR) || (ep->tag == TTEMP) ) ) return(p); } return(NULL);}LOCAL valuen scanchain(listp,p_parent)expptr listp;chainp *p_parent;/* Make value nodes from the chain hanging off a LISTBLOCK*/{ valuen lnode,rnode,new,scantree(); chainp p; p= *p_parent; if (p == NULL) return(NULL); lnode = scantree( &p->datap); rnode = scanchain(listp, &p->nextp); new = newnode(listp,lnode,rnode,0); new->rs = new; return(new->rs);}LOCAL valuen scantree(p_parent)expptr *p_parent;/* build a value node and return its address. p must point to an** exprblock an addrblock a listblock or a constblock.*/{valuen lnode, rnode,rsltnode,new;expptr opp,p;Exprp ep1,ep2;idptr idp;p = *p_parent;if(p == NULL) return(NULL);switch (p->tag) { case TCONST : return( findid(p)->initval ); case TTEMP : idp = findid(p); if(idp->assgnval) return(idp->assgnval); lnode = idp->initval; rnode = scantree( &p->tempblock.memalloc); rsltnode = findnode(p,lnode,rnode); if(rsltnode) return(rsltnode); else { new = newnode(p,lnode,rnode,0); new->rs = new; new->parent = p_parent; return(new->rs); } case TADDR : idp = findid(p); if(idp->assgnval) return(idp->assgnval); lnode = idp->initval; rnode = scantree( &p->addrblock.memoffset); rsltnode = findnode(p,lnode,rnode); if(rsltnode) {#ifdef notdef /* * This code is broken until OPINDIRECT is implemented. */ if(p->addrblock.memoffset != NULL && p->addrblock.memoffset->tag == TEXPR) addadup(p_parent,rsltnode);#endif notdef return(rsltnode); } else { new = newnode(p,lnode,rnode,0); new->rs = new; new->parent = p_parent; return(new->rs); } case TLIST : return(scanchain(p->listblock.listp,&p->listblock.listp)); default : badtag ("scantree",p->tag); case TEXPR : lnode = scantree(&p->exprblock.leftp); rnode = scantree(&p->exprblock.rightp); switch (p->exprblock.opcode) { case OPASSIGN : { Addrp ap; ap = (Addrp) p->exprblock.leftp; idp = findid(ap); killdepnodes(idp); if( ! ap->isarray ) { if(rnode->is_dead)idp->assgnval=idp->initval; else idp->assgnval = rnode; } new = newnode(p,idp->initval,NULL,NULL); appendnode(new); new->rs = new; return(new->rs); } /* * Don't optimize these... they're a real hassle. */ case OPPLUSEQ : case OPSTAREQ : { Addrp ap; ap = (Addrp) p->exprblock.leftp; idp = findid(ap); killdepnodes(idp); idp->assgnval = NULL; new = newnode(p,lnode,rnode,NULL); new->rs = new; return(new->rs); } case OPCALL : { chainp cp; if(p->exprblock.rightp) /* pretend that all variables on the arglist have just ** been assigned to i.e. kill of calculations that ** depend on them. Not necessary for CCALL(by value) */ for(cp=p->exprblock.rightp->listblock.listp; cp;cp=cp->nextp) if (cp->datap->tag == TADDR || cp->datap->tag == TTEMP){ idp = findid(cp->datap); killdepnodes(idp); idp->assgnval = NULL; } new = newnode(p,lnode,rnode,NULL); new->rs = new; return(new->rs); } case OPCONCAT: case OPADDR: case OPCOLON: case OPINDIRECT: /* * For now, do not optimize LSHIFT until OPINDIRECT * implemented. */ case OPLSHIFT: new = newnode(p,lnode,rnode,NULL); new->rs = new; return(new->rs); case OPCOMMA: badop ("scantree",OPCOMMA); break; default : rsltnode = findnode(p,lnode,rnode); if (rsltnode) { addadup(p_parent,rsltnode); return(rsltnode); } else { new = newnode(p,lnode,rnode,NULL); new->rs = new; new->parent = p_parent; appendnode(new); return(new->rs); } } }}LOCAL prunetrees()/* The only optcse.c routine that does any real work: go through the available** computations stack and eliminate redundant subtrees.*/{Addrp tempv;register duplptr dl;register valuen p;expptr t;int is_addrnode;expptr *addr_tree1 = NULL ;expptr tree2 = NULL ;for(p=current_BB->headnode;p;p=p->next) { if(p->rs == NULL) { if( addr_tree1 && tree2 ) *addr_tree1 = fixtype(mkexpr(OPCOMMA,tree2,*addr_tree1)); addr_tree1 = (expptr*) p->opp; tree2 = NULL; } if (p->n_dups ) { if (p->opp->tag == TTEMP) fprintf(diagfile,"TTEMP in prunetrees - cbb\n"); if(p->opp->tag == TADDR) is_addrnode = TRUE; else is_addrnode = FALSE; if (is_addrnode) tempv = mktemp(TYADDR,NULL); else tempv = mktemp(p->opp->exprblock.vtype, p->opp->exprblock.vleng); cse2count++; if(tree2) tree2 = fixtype(mkexpr(OPCOMMA,tree2, fixtype(mkexpr(OPASSIGN,cpexpr(tempv), (is_addrnode ? addrof(p->opp) : p->opp) )))); else tree2 = fixtype(mkexpr(OPASSIGN,cpexpr(tempv), (is_addrnode ? addrof(p->opp) : p->opp) )); if(is_addrnode) *(p->parent) = fixtype(mkexpr(OPINDIRECT,cpexpr(tempv), NULL)); else *(p->parent) = (expptr) cpexpr(tempv);/* then replaces all future instances of the calculation by references to the temporary */ for(dl=p->headduplist;dl->next;dl=dl->next) { cse1count++; frexpr(*dl->parent); if(is_addrnode) *(dl->parent) = fixtype( mkexpr(OPINDIRECT,cpexpr(tempv), NULL)); else *(dl->parent) = (expptr) cpexpr(tempv); }/* the last reference does not use a copy since the temporary can now be freed */ cse1count++; frexpr(*dl->parent); if(is_addrnode) *(dl->parent) = fixtype(mkexpr(OPINDIRECT,tempv, NULL)); else *(dl->parent) = (expptr) tempv; frtemp (tempv); } }if(addr_tree1 && tree2) *addr_tree1 = fixtype(mkexpr(OPCOMMA,tree2,*addr_tree1));}LOCAL rewritebb (bb)Bblockp bb;{ Slotp sp; expptr p; if (bb == NULL) return; else current_BB = bb; sp = current_BB->first; /* loop trough all BB slots and scan candidate expr trees when found */ for (sp = current_BB->first; ; sp = sp->next) { switch (sp->type) { case SKEQ : case SKIFN : case SKCMGOTO : case SKCALL : newnode((expptr) &sp->expr,NULL,NULL,NULL); scantree(&sp->expr); break; default : break; } if (sp == current_BB->last) break; }/* use the information built up by scantree to prune reduntant subtrees */ prunetrees(); current_BB = NULL;}/* * removes all instances of OPCOMMA from the given subexpression of * the given buffer slot */expptr rmcommaop (p,sl)expptr p;Slotp sl;{expptr leftp,rightp;chainp cp;if (!p) return (ENULL);switch (p->tag) { case TEXPR: leftp = p->exprblock.leftp; rightp = p->exprblock.rightp; leftp = rmcommaop (leftp,sl); if (p->exprblock.opcode == OPCOMMA) { optinsert (SKEQ,leftp,0,0,sl); if (p->exprblock.vleng) free ((charptr) p->exprblock.vleng); free ((charptr) p); p = rmcommaop (rightp,sl); return (p); } p->exprblock.leftp = leftp; p->exprblock.rightp = rmcommaop (rightp,sl); return (p); case TLIST: for (cp = p->listblock.listp; cp; cp = cp->nextp) cp->datap = (tagptr) rmcommaop (cp->datap,sl); return (p); case TADDR: p->addrblock.memoffset = rmcommaop (p->addrblock.memoffset,sl); return (p); default: return (p); }}/* * scans the code buffer, performing common subexpression elimination */optcse (){Slotp sl;Bblockp bb;if (debugflag[13]) return;cse1count = 0;cse2count = 0;for (sl = firstslot; sl; sl = sl->next) sl->expr = rmcommaop (sl->expr,sl);for (bb = firstblock; bb; bb = bb->next) rewritebb (bb);if (debugflag[0]) fprintf (diagfile, "%d common subexpression use%s eliminated (%d definition%s)\n", cse1count, (cse1count==1 ? "" : "s"), cse2count, (cse2count==1 ? "" : "s"));}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?