Annotation of 42BSD/usr.bin/f77/src/f77pass1/optcse.c, revision 1.1.1.1

1.1       root        1: #include "defs.h"
                      2: #include "optim.h"
                      3: 
                      4: #define MSKREGTYPES M(TYLOGICAL) | M(TYADDR) | M(TYSHORT) | M(TYLONG)
                      5: #define ISREGTYPE(x) ONEOF(x, MSKREGTYPES)
                      6: 
                      7: #define FALSE  0
                      8: #define TRUE   1
                      9: 
                     10: LOCAL Bblockp  current_BB;
                     11: LOCAL int      cse1count;      /* count of number of cse uses eliminated */
                     12: LOCAL int      cse2count;      /* count of number of cse def's eliminated */
                     13: 
                     14: 
                     15: 
                     16: 
                     17: LOCAL dumpstacks()
                     18: {
                     19:        duplptr dl;
                     20:        valuen p;
                     21:        idlptr idl;
                     22:        idptr idp;
                     23:        nodelptr nl;
                     24:        int i;
                     25: 
                     26:        fprintf(diagfile,"\n *** IDblocks ***\n");
                     27:        for(idp=current_BB->headid;idp;idp=idp->next) 
                     28:        { 
                     29:                fprintf(diagfile,
                     30:                        "idp= %d idaddr= %d initval= %d assgnval= %d \n",
                     31:                        idp, idp->idaddr, idp->initval, idp->assgnval);
                     32:                fprintf(diagfile,"nodes: ");
                     33:                i=0;
                     34:                for (nl=idp->headnodelist;nl;nl=nl->next) {
                     35:                        if(++i>20){
                     36:                                fprintf(diagfile,"\n");
                     37:                                i=0;
                     38:                        }
                     39:                        fprintf(diagfile," %d ",nl->nodep);
                     40:                }
                     41:                fprintf(diagfile,"\n");
                     42:        }
                     43: 
                     44:        fprintf(diagfile,"\n *** VALUE NODES *** \n");
                     45:        for(p=current_BB->headnode;p;p=p->next) {
                     46:                fprintf(diagfile,
                     47:                   "\np= %d opp= %d lc= %d rc= %d rs= %d is_dead= %d n_dups %d",
                     48:                   p, p->opp,p->lc,p->rc, p->rs, p->is_dead, p->n_dups);
                     49:                if (p->rs){ 
                     50:                        fprintf(diagfile,"tag= %d ",p->opp->tag);
                     51:                        if(p->opp->tag==TEXPR)
                     52:                                fprintf(diagfile,"opco= %d ",
                     53:                                    p->opp->exprblock.opcode);
                     54:                }
                     55:                fprintf(diagfile,"\n");
                     56:                fprintf(diagfile,"parent= %d dups:  ",p->parent);
                     57:                i=0;
                     58:                for(dl=p->headduplist;dl;dl=dl->next) {
                     59:                        if(++i>20){
                     60:                                fprintf(diagfile,"\n");
                     61:                                i=0;
                     62:                        }
                     63:                        fprintf(diagfile," %d ",dl->parent);
                     64:                }
                     65: 
                     66:                fprintf(diagfile,"\ndeps IDs");
                     67:                i=0;
                     68:                for(idl=p->headdeplist;idl;idl=idl->next) {
                     69:                        if(++i>20){
                     70:                                fprintf(diagfile,"\n");
                     71:                                i=0;
                     72:                        }
                     73:                        fprintf(diagfile," %d ",idl->idp);
                     74:                }
                     75:        }
                     76: }
                     77: 
                     78: 
                     79: 
                     80: LOCAL idlptr mergedeps(lnode,rnode)
                     81: valuen lnode,rnode;
                     82: /* Given two value nodes, merge the lists of identifiers on which they
                     83: ** depend to produce a new list incorporating both dependencies. Lists
                     84: ** are assumed to be ordered by increasing idp address. No duplicate identifiers
                     85: ** are generated in the output list.
                     86: */
                     87: {
                     88:        register idlptr lp,lp1,lp2;
                     89:        idlptr head;
                     90: 
                     91:        lp = lp1 = lp2 = head = NULL;
                     92:        if(lnode) lp1 = lnode->headdeplist;
                     93:        if(rnode) lp2 = rnode->headdeplist;
                     94: 
                     95:        while (lp1 || lp2) {
                     96:                if (lp) { 
                     97:                        lp->next = ALLOC(IDlist); 
                     98:                        lp = lp->next; 
                     99:                }
                    100:                else lp = head = ALLOC(IDlist);
                    101:                lp->next = 0;
                    102:                if (lp1 == 0) {
                    103:                        lp->idp = lp2->idp;
                    104:                        lp2 = lp2->next;
                    105:                }
                    106:                else if (lp2 == 0) {
                    107:                        lp->idp = lp1->idp;
                    108:                        lp1 = lp1->next; 
                    109:                }
                    110:                else if (lp1->idp < lp2->idp) {
                    111:                        lp->idp = lp1->idp;
                    112:                        lp1 = lp1->next; 
                    113:                }
                    114:                else if (lp1->idp > lp2->idp) {
                    115:                        lp->idp = lp2->idp;
                    116:                        lp2 = lp2->next; 
                    117:                }
                    118:                else {
                    119:                        lp->idp = lp1->idp;
                    120:                        lp1 = lp1->next;
                    121:                        lp2 = lp2->next;
                    122:                }
                    123:        }
                    124:        return(head);
                    125: }
                    126: 
                    127: 
                    128: 
                    129: LOCAL removenode(nodep)
                    130: valuen nodep;
                    131: /*  Removes a value node from every IDblock on the node's list of identifiers.
                    132: */
                    133: {
                    134:        register idlptr idl;
                    135:        register nodelptr nl;
                    136:        register nodelptr *addrnl;
                    137: 
                    138:        if(nodep == NULL) return ;
                    139: 
                    140:        /* loop through all identifiers */
                    141:        for(idl=nodep->headdeplist;idl;idl=idl->next)
                    142:        {
                    143:                addrnl = &(idl->idp->headnodelist);
                    144:                /* for each identifier loop through all nodes until match is found */
                    145:                for(nl = *addrnl; nl; nl = *addrnl)
                    146:                {
                    147:                        if(nl->nodep == nodep) {
                    148:                                *addrnl = nl->next;
                    149:                                free ( (charptr) nl );
                    150:                                break;
                    151:                        }
                    152:                        addrnl = &nl->next;
                    153:                }
                    154:        }
                    155:        nodep->is_dead = TRUE;
                    156: }
                    157: 
                    158: 
                    159: 
                    160: LOCAL killid(idp)
                    161: idptr idp;
                    162: /* Kill all nodes on one identifier's list of dependent nodes, i.e. remove
                    163: ** all calculations that depend on this identifier from the available 
                    164: ** values stack.  Free the list of records pointing at the dependent nodes.
                    165: */
                    166: {
                    167:        nodelptr nl1,nl2;
                    168: 
                    169:        for (nl1 = idp->headnodelist; nl1; nl1=nl2) 
                    170:        {
                    171:                nl2 = nl1->next;
                    172:                removenode(nl1->nodep);
                    173:        }
                    174:        /* the above call frees the node list record pointed at by nl1 since it frees
                    175:        ** all the node list records that reference the value node being killed
                    176:        */
                    177:        idp->headnodelist = NULL;
                    178: 
                    179: }
                    180: 
                    181: 
                    182: 
                    183: LOCAL killdepnodes(idp)
                    184: idptr idp;
                    185: /* Kill all value nodes that represent calculations which depend on
                    186: ** this identifier. If the identifier is in COMMON or EQUIVALENCE storage,
                    187: ** kill all values that depend on identifiers in COMMON or EQUIVALENCE
                    188: */
                    189: {
                    190:        int thismemno;
                    191: 
                    192:        if(idp->idaddr->addrblock.vstg == STGCOMMON) 
                    193:        {
                    194:                for(idp=current_BB->headid;idp;idp=idp->next)
                    195:                        if(idp->idaddr->addrblock.vstg == STGCOMMON)
                    196:                                killid(idp);
                    197:        }
                    198:        else if(idp->idaddr->addrblock.vstg == STGEQUIV) 
                    199:        {           
                    200:                thismemno=idp->idaddr->addrblock.memno;
                    201:                for(idp=current_BB->headid;idp;idp=idp->next)
                    202:                        if(idp->idaddr->addrblock.vstg == STGEQUIV
                    203:                            && idp->idaddr->addrblock.memno == thismemno)
                    204:                                killid(idp);
                    205:        }
                    206:        else killid(idp);
                    207: 
                    208: }
                    209: 
                    210: 
                    211: 
                    212: LOCAL appendnode(nodep)
                    213: valuen nodep;
                    214: /* Append a value node to all the IDblocks on that node's list of
                    215: ** dependent identifiers i.e., since this computation depends on
                    216: ** all the identifiers on its list then each of those identifiers should
                    217: ** include this node in their list of dependent nodes.
                    218: */
                    219: {
                    220:        register idlptr idl;
                    221:        register nodelptr nl;
                    222: 
                    223:        for(idl=nodep->headdeplist;idl;idl=idl->next)
                    224:                if(idl->idp->idaddr->tag == TADDR ||
                    225:                   idl->idp->idaddr->tag == TTEMP)
                    226:                        {
                    227:                        nl=ALLOC(NODElist);
                    228:                        nl->nodep = nodep;
                    229:                        nl->next = idl->idp->headnodelist;
                    230:                        idl->idp->headnodelist = nl;
                    231:                        }
                    232: }
                    233: 
                    234: 
                    235: 
                    236: LOCAL idlptr addadep(idp,nodep) 
                    237: idptr idp;
                    238: valuen nodep;
                    239: /* Add an identifier to the dependents list of a value node.  Dependents
                    240: ** lists are ordered by increasing idp value
                    241: */
                    242: {
                    243:        register idlptr lp1,lp2; 
                    244: 
                    245:        lp2 = ALLOC(IDlist);
                    246:        lp2->idp = idp;
                    247:        if(nodep->headdeplist == 0) {
                    248:                lp2->next = 0;
                    249:                nodep->headdeplist = lp2;
                    250:        }
                    251:        else if(idp <= nodep->headdeplist->idp) {
                    252:                lp2->next = nodep->headdeplist;
                    253:                nodep->headdeplist = lp2;
                    254:        }
                    255:        else for(lp1 = nodep->headdeplist; lp1; lp1 = lp1->next)
                    256:                if( (lp1->next == 0) || (idp <= lp1->next->idp) )
                    257:                {
                    258:                        lp2->next = lp1->next;
                    259:                        lp1->next = lp2;
                    260:                        break;
                    261:                }
                    262:        return(lp2);
                    263: }
                    264: 
                    265: 
                    266: 
                    267: LOCAL valuen newnode(expr,left,right,rslt) 
                    268: expptr expr;
                    269: valuen left,right,rslt;
                    270: /* Build a new value node            
                    271: */
                    272: {
                    273:        register valuen p;
                    274: 
                    275:        p= ALLOC(VALUEnode);
                    276:        p->opp = expr ; 
                    277:        p->parent = NULL ;
                    278:        p->lc = left;
                    279:        p->rc = right;
                    280:        p->rs = rslt;
                    281:        p->n_dups = 0;
                    282:        p->is_dead = FALSE;
                    283:        p->next=NULL;
                    284:        p->headdeplist = mergedeps(left,right);
                    285:        p->headduplist=NULL;
                    286:        if(current_BB->headnode == 0) current_BB->headnode=p;
                    287:        else if(current_BB->tailnode) current_BB->tailnode->next=p;
                    288:        current_BB->tailnode=p;
                    289: 
                    290:        return(p);
                    291: }
                    292: 
                    293: 
                    294: 
                    295: LOCAL newid(idaddr,addrof_idptr)
                    296: expptr idaddr; 
                    297: idptr *addrof_idptr;
                    298: /* Build a new IDblock and hook it on the current BB's ID list
                    299: */
                    300: {
                    301:        register idptr p;
                    302: 
                    303:        p= ALLOC(IDblock);
                    304: 
                    305: /* build a leaf value node for the identifier and put the ID on the leaf node's
                    306: ** list of dependent identifiers
                    307: */
                    308:        p->initval =  newnode(idaddr,NULL,NULL,NULL);
                    309:        p->initval->rs = p->initval;
                    310:        addadep(p,p->initval); 
                    311: 
                    312:        p->idaddr = idaddr;
                    313:        *addrof_idptr = p;
                    314:        p->headnodelist=NULL;
                    315:        p->next=NULL;
                    316: 
                    317: }
                    318: 
                    319: 
                    320: 
                    321: LOCAL addadup(parent,nodep)
                    322: expptr *parent;
                    323: valuen nodep;
                    324: 
                    325: /* A subtree has been found that duplicates the calculation represented
                    326: ** by the value node referenced by nodep : add the root of the reduntant
                    327: ** tree to the value node's list of duplicates.
                    328: */
                    329: 
                    330: {
                    331:        register duplptr dp;
                    332:        valuen child;
                    333: 
                    334:        dp = ALLOC(DUPlist);
                    335:        dp->parent = parent;
                    336:        dp->next = nodep->headduplist;
                    337:        nodep->headduplist = dp;
                    338:        ++nodep->n_dups;
                    339: 
                    340: /* Check whether either of nodep's children is also a duplicate calculation
                    341: ** and if so peel off it's most recent dup record
                    342: */
                    343: 
                    344:        if ( (child = nodep->lc) && (child->n_dups) )
                    345:        {
                    346:                dp = child->headduplist;
                    347:                child->headduplist = dp->next;
                    348:                free ( (charptr) dp );
                    349:                --child->n_dups;
                    350:        }
                    351:        if ( (child = nodep->rc) && (child->n_dups) )
                    352:        {
                    353:                dp = child->headduplist;
                    354:                child->headduplist = dp->next;
                    355:                free ( (charptr) dp );
                    356:                --child->n_dups;
                    357:        }
                    358: 
                    359: }
                    360: 
                    361: 
                    362: 
                    363: LOCAL samebase(ep1,ep2)
                    364: expptr ep1,ep2;
                    365: {
                    366:        if ( ep1->tag == ep2->tag  )       
                    367:                switch (ep2->tag) {
                    368:                case TTEMP :
                    369:                        if (ep1->tempblock.memalloc == ep2->tempblock.memalloc)
                    370:                                return (TRUE);
                    371:                        break;
                    372:                case TADDR :  
                    373:                        if (ep1->addrblock.vstg == ep2->addrblock.vstg  &&
                    374:                            ep1->addrblock.memno == ep2->addrblock.memno )
                    375:                                return(TRUE); 
                    376:                        break;
                    377:                case TCONST :
                    378:                        if( (ep1->constblock.vtype) ==
                    379:                            (ep2->constblock.vtype)  ) 
                    380:                        {
                    381:                                union Constant *ap,*bp;
                    382:                                ap= &ep1->constblock.const;
                    383:                                bp= &ep2->constblock.const;
                    384:                                switch(ep1->constblock.vtype)
                    385: 
                    386:                                {
                    387:                                case TYSHORT:
                    388:                                case TYLONG:
                    389:                                        if(ap->ci == bp->ci) return(TRUE);
                    390:                                        break;
                    391:                                case TYREAL:
                    392:                                case TYDREAL:
                    393:                                        if(ap->cd[0] == bp->cd[0]) return(TRUE);
                    394:                                        break;
                    395:                                case TYCOMPLEX:
                    396:                                case TYDCOMPLEX:
                    397:                                        if(ap->cd[0] == bp->cd[0] &&
                    398:                                            ap->cd[1] == bp->cd[1] )
                    399:                                                return(TRUE);
                    400:                                        break;
                    401:                                }
                    402:                        }
                    403:                        break;
                    404: 
                    405:                default : 
                    406:                        badtag ("samebase",ep2->tag);
                    407:                }
                    408:        return(FALSE);
                    409: }
                    410: 
                    411: 
                    412: 
                    413: LOCAL idptr findid(idaddr)
                    414: expptr idaddr;
                    415: 
                    416: /* Find an identifier's IDblock given its idaddr. If the identifier has no
                    417: ** IBblock build one
                    418: */
                    419: 
                    420: {
                    421:        register idptr idp;
                    422:        if(current_BB->headid == 0) newid(idaddr,&current_BB->headid);
                    423:        idp=current_BB->headid;
                    424: 
                    425:        do {
                    426:                if (samebase(idp->idaddr,idaddr) )  break;
                    427:                if (idp->next == 0) {
                    428:                        newid(idaddr,&idp->next);
                    429:                        idp = idp->next;
                    430:                        break;
                    431:                }
                    432:                idp = idp->next;
                    433:        }
                    434:        while(TRUE);
                    435: 
                    436:        return(idp);
                    437: }
                    438: 
                    439: 
                    440: 
                    441: LOCAL valuen findnode(ep,leftc,rightc)
                    442: expptr ep;
                    443: valuen leftc,rightc;
                    444: {
                    445:        /* Look for a matching value node in the available computations stack
                    446:        */  
                    447:        register valuen p;
                    448: 
                    449:        for ( p=current_BB->headnode; p ; p=p->next)  {
                    450:                if( ( ! p->is_dead)   &&
                    451:                    (p->lc == leftc)  &&
                    452:                    (p->rc == rightc) &&
                    453:                    ( (ep->tag == TEXPR && p->opp->tag == TEXPR 
                    454:                      && p->opp->exprblock.opcode == ep->exprblock.opcode
                    455:                      )
                    456:                    || (ep->tag == TADDR) || (ep->tag == TTEMP)
                    457:                    )
                    458:                  ) 
                    459:                        return(p);
                    460:        }
                    461:        return(NULL);
                    462: }
                    463: 
                    464: 
                    465: 
                    466: LOCAL valuen scanchain(listp,p_parent)
                    467: expptr listp;
                    468: chainp *p_parent;
                    469: 
                    470: /* Make value nodes from the chain hanging off a LISTBLOCK
                    471: */
                    472: 
                    473: {
                    474:        valuen lnode,rnode,new,scantree();
                    475:        chainp p;
                    476: 
                    477:        p= *p_parent;
                    478:        if (p == NULL) return(NULL);
                    479:        lnode = scantree( &p->datap);
                    480:        rnode = scanchain(listp, &p->nextp);
                    481:        new = newnode(listp,lnode,rnode,0);    
                    482:        new->rs = new;
                    483:        return(new->rs);
                    484: }
                    485: 
                    486: 
                    487: 
                    488: LOCAL valuen scantree(p_parent)
                    489: expptr *p_parent;
                    490: 
                    491: /* build a value node and return its address. p must point to an
                    492: ** exprblock an addrblock a listblock  or a constblock.
                    493: */
                    494: 
                    495: {
                    496: valuen lnode, rnode,rsltnode,new;
                    497: expptr opp,p;
                    498: Exprp ep1,ep2;
                    499: idptr idp;
                    500: 
                    501: p = *p_parent;
                    502: if(p == NULL) return(NULL);
                    503: 
                    504: switch (p->tag) {
                    505:        case TCONST :
                    506:                return( findid(p)->initval );
                    507:        
                    508:        case TTEMP :
                    509:                idp = findid(p);
                    510:                if(idp->assgnval) return(idp->assgnval);
                    511:        
                    512:                lnode = idp->initval;
                    513:                rnode = scantree( &p->tempblock.memalloc);
                    514:        
                    515:                rsltnode = findnode(p,lnode,rnode);
                    516:                if(rsltnode)
                    517:                        return(rsltnode);
                    518:                else { 
                    519:                        new = newnode(p,lnode,rnode,0);
                    520:                        new->rs = new;
                    521:                        new->parent = p_parent;
                    522:                        return(new->rs);
                    523:                }
                    524: 
                    525:        case TADDR :    
                    526:                idp = findid(p);
                    527:                if(idp->assgnval) return(idp->assgnval);
                    528:        
                    529:                lnode = idp->initval;
                    530:                rnode = scantree( &p->addrblock.memoffset);
                    531:        
                    532:                rsltnode = findnode(p,lnode,rnode);
                    533:                if(rsltnode) {
                    534:                        if(p->addrblock.memoffset &&
                    535:                            p->addrblock.memoffset->tag == TEXPR
                    536:                            && NULL)
                    537:                                addadup(p_parent,rsltnode);
                    538:                        return(rsltnode);
                    539:                } 
                    540:                else { 
                    541:                        new = newnode(p,lnode,rnode,0);
                    542:                        new->rs = new;
                    543:                        new->parent = p_parent;
                    544:                        return(new->rs);
                    545:                }
                    546:        
                    547:        case TLIST :
                    548:                return(scanchain(p->listblock.listp,&p->listblock.listp));
                    549:        
                    550:        default :    
                    551:                badtag ("scantree",p->tag);
                    552:        
                    553:        case TEXPR  :    
                    554:                lnode = scantree(&p->exprblock.leftp);
                    555:                rnode = scantree(&p->exprblock.rightp);
                    556:        
                    557:                switch (p->exprblock.opcode) {
                    558:                        case OPASSIGN :
                    559:                        case OPPLUSEQ :
                    560:                        case OPSTAREQ :
                    561:                                {
                    562:                                Addrp ap;
                    563:        
                    564:                                ap = (Addrp) p->exprblock.leftp;
                    565:                                idp = findid(ap);
                    566:                                killdepnodes(idp);
                    567:                                if( ! ap->isarray ) {
                    568:                                        if(rnode->is_dead)idp->assgnval=idp->initval;
                    569:                                        else idp->assgnval = rnode;
                    570:                                }
                    571:                                new = newnode(p,idp->initval,NULL,NULL);
                    572:                                appendnode(new);
                    573:                                new->rs = new;
                    574:                                return(new->rs);
                    575:                                }
                    576: 
                    577:                        case OPCALL :                    
                    578:                                {
                    579:                                chainp cp;
                    580: 
                    581:                                if(p->exprblock.rightp)
                    582: 
                    583:        /* pretend that all variables on the arglist have just
                    584:        ** been assigned to i.e. kill of calculations that 
                    585:        ** depend on them. Not necessary for CCALL(by value)
                    586:        */
                    587: 
                    588:                                for(cp=p->exprblock.rightp->listblock.listp;
                    589:                                 cp;cp=cp->nextp) 
                    590:                                        if (cp->datap->tag == TADDR ||
                    591:                                            cp->datap->tag == TTEMP){
                    592:                                                idp = findid(cp->datap);
                    593:                                                killdepnodes(idp);
                    594:                                                idp->assgnval = NULL;
                    595:                                }
                    596: 
                    597:                                new = newnode(p,lnode,rnode,NULL);
                    598:                                new->rs = new;
                    599:                                return(new->rs);
                    600:                                }
                    601: 
                    602:                        case OPCONCAT:
                    603:                        case OPADDR:
                    604:                        case OPCOLON:
                    605:                        case OPINDIRECT:
                    606:                /*
                    607:                 * For now, do not optimize LSHIFT until OPINDIRECT
                    608:                 * implemented.
                    609:                 */
                    610:                        case OPLSHIFT:
                    611:                                new = newnode(p,lnode,rnode,NULL);
                    612:                                new->rs = new;
                    613:                                return(new->rs);
                    614: 
                    615:                        case OPCOMMA:
                    616:                                badop ("scantree",OPCOMMA);
                    617:                                break;
                    618: 
                    619:                        default : 
                    620:                                rsltnode = findnode(p,lnode,rnode);
                    621:                                if (rsltnode) {
                    622:                                        addadup(p_parent,rsltnode);
                    623:                                        return(rsltnode);
                    624:                                }
                    625:                                else {
                    626:                                        new = newnode(p,lnode,rnode,NULL);
                    627:                                        new->rs = new;             
                    628:                                        new->parent = p_parent;
                    629:                                        appendnode(new);
                    630:                                        return(new->rs);
                    631:                                }
                    632:                        }
                    633:        }
                    634: }
                    635: 
                    636: 
                    637: 
                    638: LOCAL prunetrees()
                    639: 
                    640: /* The only optcse.c routine that does any real work: go through the available
                    641: ** computations stack and eliminate redundant subtrees.
                    642: */
                    643: 
                    644: {
                    645: Addrp tempv;
                    646: register duplptr dl;
                    647: register valuen p;
                    648: expptr t;
                    649: int is_addrnode;
                    650: expptr *addr_tree1 = NULL ;
                    651: expptr tree2 = NULL ;
                    652: 
                    653: for(p=current_BB->headnode;p;p=p->next) 
                    654: {
                    655:        if(p->rs == NULL) { 
                    656:                if( addr_tree1 && tree2 ) 
                    657:                     *addr_tree1 = fixtype(mkexpr(OPCOMMA,tree2,*addr_tree1));
                    658:                addr_tree1 = (expptr*) p->opp;
                    659:                tree2 = NULL;
                    660:        }
                    661:        if (p->n_dups ) {
                    662: 
                    663:                if (p->opp->tag == TTEMP)
                    664:                        fprintf(diagfile,"TTEMP in prunetrees - cbb\n");
                    665:                if(p->opp->tag == TADDR) is_addrnode = TRUE;
                    666:                else is_addrnode = FALSE;
                    667: 
                    668:                if (is_addrnode)
                    669:                        tempv = mktemp(TYADDR,NULL);
                    670:                else
                    671:                        tempv = mktemp(p->opp->exprblock.vtype,
                    672:                            p->opp->exprblock.vleng);
                    673:                cse2count++;
                    674: 
                    675:                if(tree2)
                    676:                        tree2 = fixtype(mkexpr(OPCOMMA,tree2,
                    677:                                fixtype(mkexpr(OPASSIGN,cpexpr(tempv),
                    678:                                (is_addrnode ? addrof(p->opp) :  p->opp)
                    679:                                ))));
                    680:                else
                    681:                        tree2 = fixtype(mkexpr(OPASSIGN,cpexpr(tempv),
                    682:                                (is_addrnode ? addrof(p->opp) :  p->opp)
                    683:                                ));
                    684: 
                    685:                if(is_addrnode)
                    686:                        *(p->parent) = fixtype(mkexpr(OPINDIRECT,cpexpr(tempv), NULL));
                    687:                else
                    688:                        *(p->parent) = (expptr) cpexpr(tempv);
                    689: 
                    690: /* then replaces all future instances of the calculation by references to
                    691:    the temporary */
                    692: 
                    693:                for(dl=p->headduplist;dl->next;dl=dl->next) {
                    694:                        cse1count++;
                    695:                        frexpr(*dl->parent);
                    696:                        if(is_addrnode)
                    697:                                *(dl->parent) = fixtype(
                    698:                                        mkexpr(OPINDIRECT,cpexpr(tempv), NULL));
                    699:                        else
                    700:                                *(dl->parent) = (expptr) cpexpr(tempv);
                    701:                }
                    702: 
                    703: /* the last reference does not use a copy since the temporary can
                    704:    now be freed */
                    705: 
                    706:                cse1count++;
                    707:                frexpr(*dl->parent);
                    708:                if(is_addrnode)
                    709:                        *(dl->parent) = fixtype(mkexpr(OPINDIRECT,tempv, NULL));
                    710:                else
                    711:                        *(dl->parent) = (expptr) tempv;
                    712: 
                    713:                frtemp (tempv);
                    714:        }                  
                    715: }
                    716: if(addr_tree1 && tree2)
                    717:        *addr_tree1 = fixtype(mkexpr(OPCOMMA,tree2,*addr_tree1));
                    718: }
                    719: 
                    720: 
                    721: 
                    722: LOCAL rewritebb (bb)
                    723: Bblockp bb;
                    724: {
                    725:        Slotp sp; 
                    726:        expptr p;
                    727: 
                    728:        if (bb == NULL)
                    729:                return;
                    730:        else
                    731:                current_BB = bb;
                    732:        sp = current_BB->first;
                    733: 
                    734:        /* loop trough all BB slots and scan candidate expr trees when found */
                    735: 
                    736:        for (sp = current_BB->first; ; sp = sp->next)
                    737:                {
                    738:                switch (sp->type)
                    739:                    {
                    740:                    case SKEQ : 
                    741:                    case SKIFN : 
                    742:                    case SKCMGOTO :
                    743:                    case SKCALL :
                    744:                        newnode((expptr) &sp->expr,NULL,NULL,NULL);
                    745:                        scantree(&sp->expr); 
                    746:                        break;
                    747: 
                    748:                    default  : 
                    749:                        break;
                    750:                    }
                    751:                if (sp == current_BB->last) break;
                    752:                }
                    753: 
                    754: /* use the information built up by scantree to prune reduntant subtrees */
                    755:        prunetrees();
                    756: 
                    757:        current_BB = NULL;
                    758: }
                    759: 
                    760: 
                    761: 
                    762: /*
                    763:  *  removes all instances of OPCOMMA from the given subexpression of
                    764:  *  the given buffer slot
                    765:  */
                    766: 
                    767: expptr rmcommaop (p,sl)
                    768: expptr p;
                    769: Slotp  sl;
                    770: 
                    771: {
                    772: expptr leftp,rightp;
                    773: chainp cp;
                    774: 
                    775: if (!p)
                    776:        return (ENULL);
                    777: switch (p->tag)
                    778:        {
                    779:        case TEXPR:
                    780:                leftp = p->exprblock.leftp;
                    781:                rightp = p->exprblock.rightp;
                    782:                leftp = rmcommaop (leftp,sl);
                    783:                if (p->exprblock.opcode == OPCOMMA)
                    784:                        {
                    785:                        optinsert (SKEQ,leftp,0,0,sl);
                    786:                        if (p->exprblock.vleng)
                    787:                                free ((charptr) p->exprblock.vleng);
                    788:                        free ((charptr) p);
                    789:                        p = rmcommaop (rightp,sl);
                    790:                        return (p);
                    791:                        }
                    792:                p->exprblock.leftp = leftp;
                    793:                p->exprblock.rightp = rmcommaop (rightp,sl);
                    794:                return (p);
                    795: 
                    796:        case TLIST:
                    797:                for (cp = p->listblock.listp; cp; cp = cp->nextp)
                    798:                        cp->datap = (tagptr) rmcommaop (cp->datap,sl);
                    799:                return (p);
                    800: 
                    801:        default:
                    802:                return (p);
                    803:        }
                    804: }
                    805: 
                    806: 
                    807: 
                    808: /*
                    809:  *  scans the code buffer, performing common subexpression elimination
                    810:  */
                    811: 
                    812: optcse ()
                    813: 
                    814: {
                    815: Slotp  sl;
                    816: Bblockp        bb;
                    817: 
                    818: if (debugflag[13])
                    819:        return;
                    820: 
                    821: cse1count = 0;
                    822: cse2count = 0;
                    823: for (sl = firstslot; sl; sl = sl->next)
                    824:        sl->expr = rmcommaop (sl->expr,sl);
                    825: for (bb = firstblock; bb; bb = bb->next)
                    826:        rewritebb (bb);
                    827: 
                    828: if (debugflag[0])
                    829:        fprintf (diagfile,
                    830:                "%d common subexpression use%s eliminated (%d definition%s)\n",
                    831:                cse1count, (cse1count==1 ? "" : "s"),
                    832:                cse2count, (cse2count==1 ? "" : "s"));
                    833: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.