|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.