optcse.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 947 行 · 第 1/2 页
C
947 行
#ifndef lintstatic char *sccsid = "@(#)optcse.c 4.1 (ULTRIX) 7/17/90";#endif lint/************************************************************************ * * * Copyright (c) 1984 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * optcse.c * * Common subexpression elimination routines, F77 compiler pass 1. * * University of Utah CS Dept modification history: * * $Log: optcse.c,v $ * Revision 2.4 84/10/29 04:40:48 donn * Problem with conversions -- two expressions headed by a conversion may be * identical in structure but different in type, thus type must be checked in * findnode(). This was causing a subscript to become REAL*8 type... * * Revision 2.3 84/08/04 20:38:53 donn * Added fix from Jerry Berkman for an earlier fix from Alastair Fyfe -- * samebase() should treat EQUIVALENCEd variables just as daintily as * COMMON variables. * * Revision 2.2 84/08/01 16:04:33 donn * Changed rmcommaop so that it does subscripts too. * * Revision 2.1 84/07/19 12:03:44 donn * Changed comment headers for UofU. * * Revision 1.5 84/07/09 14:43:05 donn * Added changes to make OPPLUSEQ and OPSTAREQ expressions ineligible for * CSE, since I can't think of a simple way to handle them and they are broken * in the previous version, where they were treated like OPASSIGN -- this * fails because CSE would think that the value of the lhs and rhs were equal. * * Revision 1.4 84/06/08 11:43:35 donn * Yet another way of handling the bug with COMMON -- this one is from Alastair * Fyfe at Sun. I backed out the old fix. * * Revision 1.3 84/03/07 19:25:14 donn * Changed method of handling COMMON bug -- COMMON variables are now treated * like array elements and hence are ineligible for CSE. * * Revision 1.2 84/02/26 03:30:47 donn * Fixed bug in evaluation graph construction that caused two variables in * common to be considered identical if they were merely in the same common, * rather than in the same common at the same offset. * */#include "defs.h"#include "optim.h"#define FALSE 0#define TRUE 1LOCAL Bblockp current_BB;LOCAL int cse1count; /* count of number of cse uses eliminated */LOCAL int cse2count; /* count of number of cse def's eliminated */LOCAL dumpstacks(){ duplptr dl; valuen p; idlptr idl; idptr idp; nodelptr nl; int i; fprintf(diagfile,"\n *** IDblocks ***\n"); for(idp=current_BB->headid;idp;idp=idp->next) { fprintf(diagfile, "idp= %d idaddr= %d initval= %d assgnval= %d \n", idp, idp->idaddr, idp->initval, idp->assgnval); fprintf(diagfile,"nodes: "); i=0; for (nl=idp->headnodelist;nl;nl=nl->next) { if(++i>20){ fprintf(diagfile,"\n"); i=0; } fprintf(diagfile," %d ",nl->nodep); } fprintf(diagfile,"\n"); } fprintf(diagfile,"\n *** VALUE NODES *** \n"); for(p=current_BB->headnode;p;p=p->next) { fprintf(diagfile, "\np= %d opp= %d lc= %d rc= %d rs= %d is_dead= %d n_dups %d", p, p->opp,p->lc,p->rc, p->rs, p->is_dead, p->n_dups); if (p->rs){ fprintf(diagfile,"tag= %d ",p->opp->tag); if(p->opp->tag==TEXPR) fprintf(diagfile,"opco= %d ", p->opp->exprblock.opcode); } fprintf(diagfile,"\n"); fprintf(diagfile,"parent= %d dups: ",p->parent); i=0; for(dl=p->headduplist;dl;dl=dl->next) { if(++i>20){ fprintf(diagfile,"\n"); i=0; } fprintf(diagfile," %d ",dl->parent); } fprintf(diagfile,"\ndeps IDs"); i=0; for(idl=p->headdeplist;idl;idl=idl->next) { if(++i>20){ fprintf(diagfile,"\n"); i=0; } fprintf(diagfile," %d ",idl->idp); } }}LOCAL idlptr mergedeps(lnode,rnode)valuen lnode,rnode;/* Given two value nodes, merge the lists of identifiers on which they** depend to produce a new list incorporating both dependencies. Lists** are assumed to be ordered by increasing idp address. No duplicate identifiers** are generated in the output list.*/{ register idlptr lp,lp1,lp2; idlptr head; lp = lp1 = lp2 = head = NULL; if(lnode) lp1 = lnode->headdeplist; if(rnode) lp2 = rnode->headdeplist; while (lp1 || lp2) { if (lp) { lp->next = ALLOC(IDlist); lp = lp->next; } else lp = head = ALLOC(IDlist); lp->next = 0; if (lp1 == 0) { lp->idp = lp2->idp; lp2 = lp2->next; } else if (lp2 == 0) { lp->idp = lp1->idp; lp1 = lp1->next; } else if (lp1->idp < lp2->idp) { lp->idp = lp1->idp; lp1 = lp1->next; } else if (lp1->idp > lp2->idp) { lp->idp = lp2->idp; lp2 = lp2->next; } else { lp->idp = lp1->idp; lp1 = lp1->next; lp2 = lp2->next; } } return(head);}LOCAL removenode(nodep)valuen nodep;/* Removes a value node from every IDblock on the node's list of identifiers.*/{ register idlptr idl; register nodelptr nl; register nodelptr *addrnl; if(nodep == NULL) return ; /* loop through all identifiers */ for(idl=nodep->headdeplist;idl;idl=idl->next) { addrnl = &(idl->idp->headnodelist); /* for each identifier loop through all nodes until match is found */ for(nl = *addrnl; nl; nl = *addrnl) { if(nl->nodep == nodep) { *addrnl = nl->next; free ( (charptr) nl ); break; } addrnl = &nl->next; } } nodep->is_dead = TRUE;}LOCAL killid(idp)idptr idp;/* Kill all nodes on one identifier's list of dependent nodes, i.e. remove** all calculations that depend on this identifier from the available ** values stack. Free the list of records pointing at the dependent nodes.*/{ nodelptr nl1,nl2; for (nl1 = idp->headnodelist; nl1; nl1=nl2) { nl2 = nl1->next; removenode(nl1->nodep); } /* the above call frees the node list record pointed at by nl1 since it frees ** all the node list records that reference the value node being killed */ idp->headnodelist = NULL;}LOCAL killdepnodes(idp)idptr idp;/* Kill all value nodes that represent calculations which depend on** this identifier. If the identifier is in COMMON or EQUIVALENCE storage,** kill all values that depend on identifiers in COMMON or EQUIVALENCE*/{ int thismemno; if(idp->idaddr->addrblock.vstg == STGCOMMON) { for(idp=current_BB->headid;idp;idp=idp->next) if(idp->idaddr->addrblock.vstg == STGCOMMON) killid(idp); } else if(idp->idaddr->addrblock.vstg == STGEQUIV) { thismemno=idp->idaddr->addrblock.memno; for(idp=current_BB->headid;idp;idp=idp->next) if(idp->idaddr->addrblock.vstg == STGEQUIV && idp->idaddr->addrblock.memno == thismemno) killid(idp); } else killid(idp);}LOCAL appendnode(nodep)valuen nodep;/* Append a value node to all the IDblocks on that node's list of** dependent identifiers i.e., since this computation depends on** all the identifiers on its list then each of those identifiers should** include this node in their list of dependent nodes.*/{ register idlptr idl; register nodelptr nl; for(idl=nodep->headdeplist;idl;idl=idl->next) if(idl->idp->idaddr->tag == TADDR || idl->idp->idaddr->tag == TTEMP) { nl=ALLOC(NODElist); nl->nodep = nodep; nl->next = idl->idp->headnodelist; idl->idp->headnodelist = nl; }}LOCAL idlptr addadep(idp,nodep) idptr idp;valuen nodep;/* Add an identifier to the dependents list of a value node. Dependents** lists are ordered by increasing idp value*/{ register idlptr lp1,lp2; lp2 = ALLOC(IDlist); lp2->idp = idp; if(nodep->headdeplist == 0) { lp2->next = 0; nodep->headdeplist = lp2; } else if(idp <= nodep->headdeplist->idp) { lp2->next = nodep->headdeplist; nodep->headdeplist = lp2; } else for(lp1 = nodep->headdeplist; lp1; lp1 = lp1->next) if( (lp1->next == 0) || (idp <= lp1->next->idp) ) { lp2->next = lp1->next; lp1->next = lp2; break; } return(lp2);}LOCAL valuen newnode(expr,left,right,rslt) expptr expr;valuen left,right,rslt;/* Build a new value node */{ register valuen p; p= ALLOC(VALUEnode); p->opp = expr ; p->parent = NULL ; p->lc = left; p->rc = right; p->rs = rslt; p->n_dups = 0; p->is_dead = FALSE; p->next=NULL; p->headdeplist = mergedeps(left,right); p->headduplist=NULL; if(current_BB->headnode == 0) current_BB->headnode=p; else if(current_BB->tailnode) current_BB->tailnode->next=p; current_BB->tailnode=p; return(p);}LOCAL newid(idaddr,addrof_idptr)expptr idaddr; idptr *addrof_idptr;/* Build a new IDblock and hook it on the current BB's ID list*/{ register idptr p; p= ALLOC(IDblock);/* build a leaf value node for the identifier and put the ID on the leaf node's** list of dependent identifiers*/ p->initval = newnode(idaddr,NULL,NULL,NULL); p->initval->rs = p->initval; addadep(p,p->initval); p->idaddr = idaddr; *addrof_idptr = p; p->headnodelist=NULL; p->next=NULL;}LOCAL addadup(parent,nodep)expptr *parent;valuen nodep;/* A subtree has been found that duplicates the calculation represented** by the value node referenced by nodep : add the root of the reduntant** tree to the value node's list of duplicates.*/{ register duplptr dp; valuen child; dp = ALLOC(DUPlist); dp->parent = parent; dp->next = nodep->headduplist; nodep->headduplist = dp; ++nodep->n_dups;/* Check whether either of nodep's children is also a duplicate calculation** and if so peel off it's most recent dup record*/ if ( (child = nodep->lc) && (child->n_dups) ) { dp = child->headduplist; child->headduplist = dp->next; free ( (charptr) dp ); --child->n_dups; } if ( (child = nodep->rc) && (child->n_dups) ) { dp = child->headduplist; child->headduplist = dp->next; free ( (charptr) dp ); --child->n_dups; }}LOCAL samebase(ep1,ep2)expptr ep1,ep2;{ if ( ep1->tag == ep2->tag ) switch (ep2->tag) { case TTEMP : if (ep1->tempblock.memalloc == ep2->tempblock.memalloc) return (TRUE); break; case TADDR : if (ep1->addrblock.vstg == ep2->addrblock.vstg) { switch(ep1->addrblock.vstg) { case STGEQUIV: case STGCOMMON: if (ep1->addrblock.memno == ep2->addrblock.memno && ISCONST(ep1->addrblock.memoffset) && ISCONST(ep2->addrblock.memoffset) && ep1->addrblock.memoffset->constblock.const.ci == ep2->addrblock.memoffset->constblock.const.ci ) { return(TRUE); } break; default: if (ep1->addrblock.memno == ep2->addrblock.memno ) { return(TRUE); } } } break; case TCONST : if( (ep1->constblock.vtype) == (ep2->constblock.vtype) ) { union Constant *ap,*bp; ap= &ep1->constblock.const; bp= &ep2->constblock.const; switch(ep1->constblock.vtype)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?