Annotation of researchv9/cmd/sun/c2/livereg.c, revision 1.1

1.1     ! root        1: 
        !             2: #ifndef lint
        !             3: static char sccsid[] = "@(#)livereg.c 1.1 86/02/03 Copyr 1985 Sun Micro";
        !             4: #endif
        !             5: 
        !             6: /*
        !             7:  * Copyright (c) 1985 by Sun Microsystems, Inc.
        !             8:  */
        !             9: 
        !            10: #include "as.h"
        !            11: #include "c2.h"
        !            12: 
        !            13: #define MAXLIVE 10000
        !            14: NODE *heap_o_nodes[MAXLIVE];
        !            15: NODE **nextnode = heap_o_nodes;
        !            16: int nlive = 0;
        !            17: 
        !            18: static void
        !            19: pushlive( m )
        !            20:     NODE *m;
        !            21: {
        !            22:     if (++nlive>MAXLIVE) sys_error("nursury overflow\n");
        !            23:     *(nextnode++) = m;
        !            24: }
        !            25: 
        !            26: static NODE *
        !            27: poplive()
        !            28: {
        !            29:     if (nlive<=0) return (NODE *)NULL;
        !            30:     nlive--;
        !            31:     return *(--nextnode);
        !            32: }
        !            33: 
        !            34: #define killreg(m) (m)
        !            35: 
        !            36: regmask
        !            37: compute_meet( mp, ll, lr )
        !            38:     NODE *mp;
        !            39:     regmask ll, lr;
        !            40: {
        !            41:     /* the liveset compuation of a "meet" node: conditional branch */
        !            42:     /* return ((ll|lr)&~killreg(mp->rset))|mp->ruse; */
        !            43:     return (addmask(submask(addmask(ll, lr) , killreg(mp->rset)), mp->ruse));
        !            44: }
        !            45: 
        !            46: regmask
        !            47: compute_indirect( mp )
        !            48:     NODE *mp;
        !            49: {
        !            50:     register NODE *np = mp->forw->forw;
        !            51:     regmask r; 
        !            52: 
        !            53:     r  = regmask0;
        !            54:     while (np->op==OP_CSWITCH){
        !            55:        r = addmask( r, np->rlive);
        !            56:        np=np->forw;
        !            57:     }
        !            58:     /* return (r&~killreg(mp->rset)) | mp->ruse; */
        !            59:     return ( addmask( submask( r, killreg(mp->rset) ), mp->ruse ));
        !            60: }
        !            61: 
        !            62: regmask
        !            63: compute_normal( mp, ll )
        !            64:     NODE *mp;
        !            65:     regmask ll;
        !            66: {
        !            67:     /* the liveset compuattion of a normal, boring instruction */
        !            68:     /* return (ll & ~killreg(mp->rset)) | mp->ruse ; */
        !            69:     return ( addmask( submask( ll, killreg(mp->rset)), mp->ruse));
        !            70: }
        !            71: 
        !            72: livereg(){
        !            73:     /*
        !            74:      * Each node in the program has a field called rlive; this is where
        !            75:      * we keep track of registers and pieces of registers that will
        !            76:      * be used before they're next written. This set represents the state
        !            77:      * of the registers BEFORE entering the node.
        !            78:      * Here's our strategy:
        !            79:      *  A) find all the return nodes: they kill all register except d0/d1.
        !            80:      *     put them on the stack. as well as unconditional jumps ( this gets
        !            81:      *     us into all loops, and will get better when we get smarter. )
        !            82:      *  B) if the stack is empty, we're done; else take a node off the stack.
        !            83:      *  C) look at the predecessor node. It is one of these:
        !            84:      *    i) a label: has the same liveset as its successor. Find all of the
        !            85:      *       uses of the label we can, and for each, compute:
        !            86:      *       a) if an unconditional branch, then liveset  is same as label's. If
        !            87:      *          it is different, change it and put it on the stack. 
        !            88:      *          (Stacking may be superfluous here...we'll see).
        !            89:      *       b) a binary (conditional) branch. compute liveset as the product
        !            90:      *          of the livesets of its successors, plus the registers it reads,
        !            91:      *          less those it writes . If this set changes
        !            92:      *          from previous value, put the node on the stack.
        !            93:      *       c) A multiway branch: same as binary branch.
        !            94:      *   ii) an unconditional branch: liveset does not depend on successor.
        !            95:      *       go back to step B).
        !            96:      *  iii) a conditional branch. Compute as i.b) above.  <If value 
        !            97:      *       does not change , go back to step B and get a new node, 
        !            98:      *       else continue.> <<-- this may be wrong.
        !            99:      *   iv) a multiway branch: same as conditional branch.
        !           100:      *    v) a straight-line instruction: liveset is successor liveset, plus
        !           101:      *       registers it sets, less those it reads. continue back.
        !           102:      * D) Loop on step (C) until we either stop because of a stable branch,
        !           103:      *    ( see C.ii , C.iii), or until we fall off the beginning. Then
        !           104:      *    go back to B.
        !           105:      */
        !           106: 
        !           107:     register NODE * p, *puse, *csw;
        !           108:     regmask l, newl;
        !           109: 
        !           110:     for (p=first.forw; p != &first; p=p->forw){
        !           111:        /*
        !           112:         * recompute live sets starting from null sets --
        !           113:         * This is a last-minute kludge for 3.0, to patch over a
        !           114:         * problem that occurs in content() (failure to update
        !           115:         * live sets when a constant or memory reference is replaced
        !           116:         * by a register).  Remove the following assignment when the
        !           117:         * problem is fixed correctly.
        !           118:         */
        !           119:        p->rlive = regmask0;
        !           120:        if (p->op == OP_EXIT){
        !           121:            p->rlive = compute_normal( p, regmask_all );
        !           122:            p->rlive = submask( p->rlive, MAKERMASK( CCREG, LR) );
        !           123:            p->rlive = submask( p->rlive, MAKERMASK( FPCCREG, LR) );
        !           124:            p->rlive = submask( p->rlive, MAKERMASK( FP0REG, LR) );
        !           125:            p->rlive = submask( p->rlive, MAKERMASK( FP0REG+1, LR) );
        !           126:            p->rlive = submask( p->rlive, MAKERMASK( A0REG, LR) );
        !           127:            p->rlive = submask( p->rlive, MAKERMASK( A0REG+1, LR) );
        !           128:            pushlive( p );
        !           129:        } else if (p->op==OP_JUMP && p->subop==JALL){
        !           130:            pushlive( p );
        !           131:        } else if (p->op==OP_BRANCH){
        !           132:            p->rlive = regmask_all; /* don't know -- must consider all live */
        !           133:            pushlive( p );
        !           134:        }
        !           135:     }
        !           136: 
        !           137:     while ((p=poplive())!=NULL){
        !           138:        l = p->rlive; 
        !           139:        while( (p=p->back) != &first ){
        !           140:            switch (p->op){
        !           141:            case OP_LABEL:
        !           142:                p->rlive = l;
        !           143:                for (puse=p->luse; puse ; puse=puse->lnext){
        !           144:                    /* its a jump */
        !           145:                    if (puse->op ==OP_CSWITCH){
        !           146:                        /* part of a multi-way branch */
        !           147:                        if (!samemask( puse->rlive, l )){
        !           148:                            csw = puse;
        !           149:                            puse->rlive=l;
        !           150:                            while (csw->op != OP_JUMP)
        !           151:                                csw=csw->back;
        !           152:                            /* now found indirect jump */
        !           153:                            newl = compute_indirect(csw);
        !           154:                            if (!samemask( csw->rlive , newl) ){
        !           155:                                csw->rlive = newl;
        !           156:                                pushlive( csw );
        !           157:                            }
        !           158:                        }
        !           159:                        continue;
        !           160:                    } else if (puse->subop == JALL){
        !           161:                        newl = l;
        !           162:                    } else {
        !           163:                        newl = compute_meet( puse, puse->forw->rlive, l);
        !           164:                    }
        !           165:                    if (!samemask( puse->rlive , newl) ){
        !           166:                        puse->rlive = newl;
        !           167:                        pushlive( puse );
        !           168:                    }
        !           169:                }
        !           170:                continue;
        !           171:            case OP_JUMP:
        !           172:            case OP_DJMP:
        !           173:                if (p->subop == JALL)
        !           174:                    goto popnew;
        !           175:                else if (p->subop == JIND){
        !           176:                    newl = compute_indirect( p );
        !           177:                }else{
        !           178:                    newl = compute_meet( p,p->forw->rlive, p->luse->rlive );
        !           179:                }
        !           180:                p->rlive = l = newl;
        !           181:                continue;
        !           182:            case OP_CSWITCH:
        !           183:                goto popnew;
        !           184:            case OP_BRANCH:
        !           185:                /* know nothing about its behavior--guess the worst*/
        !           186:                l = regmask_all;
        !           187:                continue;
        !           188:            case OP_EXIT:
        !           189:                goto popnew;
        !           190:            default:
        !           191:                l = p->rlive = compute_normal( p, l);
        !           192:                continue;
        !           193:            }
        !           194:        }
        !           195:     popnew:;
        !           196:     }
        !           197: }

unix.superglobalmegacorp.com

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