Annotation of lucent/sys/src/alef/k/regopt.c, revision 1.1.1.1

1.1       root        1: #include <u.h>
                      2: #include <libc.h>
                      3: #include <bio.h>
                      4: #include <ctype.h>
                      5: #define Extern extern
                      6: #include "parl.h"
                      7: #include "globl.h"
                      8: 
                      9: #define        COL1    32
                     10: 
                     11: Node dummy;
                     12: 
                     13: int
                     14: sval(long v)
                     15: {
                     16: 
                     17:        if(v >= -(1<<12) && v < (1<<12))
                     18:                return 1;
                     19:        return 0;
                     20: }
                     21: 
                     22: Reg*
                     23: rega(void)
                     24: {
                     25:        Reg *r;
                     26: 
                     27:        r = freer;
                     28:        if(r == R)
                     29:                r = malloc(sizeof(Reg));
                     30:        else
                     31:                freer = r->next;
                     32: 
                     33:        *r = zreg;
                     34:        return r;
                     35: }
                     36: 
                     37: int
                     38: rcmp(void *a1, void *a2)
                     39: {
                     40:        Rgn *p1, *p2;
                     41:        int c1, c2;
                     42: 
                     43:        p1 = a1;
                     44:        p2 = a2;
                     45:        c1 = p2->cost;
                     46:        c2 = p1->cost;
                     47:        if(c1 -= c2)
                     48:                return c1;
                     49:        return p2->varno - p1->varno;
                     50: }
                     51: 
                     52: void
                     53: regopt(Inst *p)
                     54: {
                     55:        Reg *r, *r1, *r2;
                     56:        int i, z;
                     57:        long initpc, val;
                     58:        ulong vreg;
                     59:        Bits bit;
                     60:        Inst *p1;
                     61:        struct
                     62:        {
                     63:                long    m;
                     64:                long    c;
                     65:                Reg*    p;
                     66:        } log5[6], *lp;
                     67: 
                     68:        initpc = 0;
                     69:        firstr = R;
                     70:        lastr = R;
                     71:        nvar = 0;
                     72:        regbits = 0;
                     73:        for(z=0; z<BITS; z++) {
                     74:                externs.b[z] = 0;
                     75:                param.b[z] = 0;
                     76:                consts.b[z] = 0;
                     77:                addrs.b[z] = 0;
                     78:        }
                     79: 
                     80:        /*
                     81:         * pass 1
                     82:         * build aux data structure
                     83:         * allocate pcs
                     84:         * find use and set of variables
                     85:         */
                     86:        val = 5L * 5L * 5L * 5L * 5L;
                     87:        lp = log5;
                     88:        for(i=0; i<5; i++) {
                     89:                lp->m = val;
                     90:                lp->c = 0;
                     91:                lp->p = R;
                     92:                val /= 5L;
                     93:                lp++;
                     94:        }
                     95: 
                     96:        for(; p != P; p = p->next) {
                     97:                switch(p->op) {
                     98:                case ADATA:
                     99:                case ADYNT:
                    100:                case AINIT:
                    101:                case AGLOBL:
                    102:                case ANAME:
                    103:                        continue;
                    104:                }
                    105:                r = rega();
                    106:                if(firstr == R) {
                    107:                        initpc = p->pc;
                    108:                        firstr = r;
                    109:                        lastr = r;
                    110:                } else {
                    111:                        lastr->next = r;
                    112:                        r->p1 = lastr;
                    113:                        lastr->s1 = r;
                    114:                        lastr = r;
                    115:                }
                    116:                r->prog = p;
                    117:                r->pc = p->pc;
                    118: 
                    119:                lp = log5;
                    120:                for(i=0; i<5; i++) {
                    121:                        lp->c--;
                    122:                        if(lp->c <= 0) {
                    123:                                lp->c = lp->m;
                    124:                                if(lp->p != R)
                    125:                                        lp->p->log5 = r;
                    126:                                lp->p = r;
                    127:                                (lp+1)->c = 0;
                    128:                                break;
                    129:                        }
                    130:                        lp++;
                    131:                }
                    132: 
                    133:                r1 = r->p1;
                    134:                if(r1 != R)
                    135:                switch(r1->prog->op) {
                    136:                case ARETURN:
                    137:                case AJMP:
                    138:                case ARETT:
                    139:                        r->p1 = R;
                    140:                        r1->s1 = R;
                    141:                }
                    142: 
                    143:                /*
                    144:                 * left side always read
                    145:                 */
                    146:                bit = mkvar(&p->src1, p->op==AMOVW);
                    147:                for(z=0; z<BITS; z++)
                    148:                        r->use1.b[z] |= bit.b[z];
                    149: 
                    150:                /*
                    151:                 * right side depends on opcode
                    152:                 */
                    153:                bit = mkvar(&p->dst, 0);
                    154:                if(bany(&bit))
                    155:                switch(p->op) {
                    156:                default:
                    157:                        diag(ZeroN, "reg: unknown op: %d", p->op);
                    158:                        break;
                    159: 
                    160:                /*
                    161:                 * right side write
                    162:                 */
                    163:                case ANOP:
                    164:                case AMOVB:
                    165:                case AMOVBU:
                    166:                case AMOVH:
                    167:                case AMOVHU:
                    168:                case AMOVW:
                    169:                case AFMOVF:
                    170:                        for(z=0; z<BITS; z++)
                    171:                                r->set.b[z] |= bit.b[z];
                    172:                        break;
                    173: 
                    174:                /*
                    175:                 * funny
                    176:                 */
                    177:                case AFMOVD:
                    178:                case ARETURN:
                    179:                case AJMPL:
                    180:                        for(z=0; z<BITS; z++)
                    181:                                addrs.b[z] |= bit.b[z];
                    182:                        break;
                    183:                }
                    184:        }
                    185:        if(firstr == R)
                    186:                return;
                    187: 
                    188:        /*
                    189:         * pass 2
                    190:         * turn branch references to pointers
                    191:         * build back pointers
                    192:         */
                    193:        for(r = firstr; r != R; r = r->next) {
                    194:                p = r->prog;
                    195:                if(p->dst.type == A_BRANCH) {
                    196:                        val = p->dst.ival;
                    197:                        r1 = firstr;
                    198:                        while(r1 != R) {
                    199:                                r2 = r1->log5;
                    200:                                if(r2 != R && val >= r2->pc) {
                    201:                                        r1 = r2;
                    202:                                        continue;
                    203:                                }
                    204:                                if(r1->pc == val)
                    205:                                        break;
                    206:                                r1 = r1->next;
                    207:                        }
                    208:                        if(r1 == R) {
                    209:                                dummy.srcline = p->lineno;
                    210:                                diag(&dummy, "ref not found\n%i", p);
                    211:                                continue;
                    212:                        }
                    213:                        if(r1 == r) {
                    214:                                dummy.srcline = p->lineno;
                    215:                                diag(&dummy, "ref to self\n%i", p);
                    216:                                continue;
                    217:                        }
                    218:                        r->s2 = r1;
                    219:                        r->p2next = r1->p2;
                    220:                        r1->p2 = r;
                    221:                }
                    222:        }
                    223:        if(opt('R')) {
                    224:                p = firstr->prog;
                    225:                print("\n%L %a\n", p->lineno, &p->src1);
                    226:        }
                    227: 
                    228:        /*
                    229:         * pass 2.5
                    230:         * find looping structure
                    231:         */
                    232:        for(r = firstr; r != R; r = r->next)
                    233:                r->active = 0;
                    234:        change = 0;
                    235:        loopit(firstr);
                    236:        if(opt('R') && opt('v')) {
                    237:                print("\nlooping structure:\n");
                    238:                for(r = firstr; r != R; r = r->next) {
                    239:                        print("%d:%i", r->loop, r->prog);
                    240:                        for(z=0; z<BITS; z++)
                    241:                                bit.b[z] = r->use1.b[z] |
                    242:                                        r->use2.b[z] | r->set.b[z];
                    243:                        if(bany(&bit)) {
                    244:                                print("%|", COL1);
                    245:                                if(bany(&r->use1))
                    246:                                        print(" u1=%B", r->use1);
                    247:                                if(bany(&r->use2))
                    248:                                        print(" u2=%B", r->use2);
                    249:                                if(bany(&r->set))
                    250:                                        print(" st=%B", r->set);
                    251:                        }
                    252:                        print("\n");
                    253:                }
                    254:        }
                    255: 
                    256:        /*
                    257:         * pass 3
                    258:         * iterate propagating usage
                    259:         *      back until flow graph is complete
                    260:         */
                    261: loop1:
                    262:        change = 0;
                    263:        for(r = firstr; r != R; r = r->next)
                    264:                r->active = 0;
                    265:        for(r = firstr; r != R; r = r->next)
                    266:                if(r->prog->op == ARETURN)
                    267:                        prop(r, zbits, zbits);
                    268: loop11:
                    269:        /* pick up unreachable code */
                    270:        i = 0;
                    271:        for(r = firstr; r != R; r = r1) {
                    272:                r1 = r->next;
                    273:                if(r1 && r1->active && !r->active) {
                    274:                        prop(r, zbits, zbits);
                    275:                        i = 1;
                    276:                }
                    277:        }
                    278:        if(i)
                    279:                goto loop11;
                    280:        if(change)
                    281:                goto loop1;
                    282: 
                    283: 
                    284:        /*
                    285:         * pass 4
                    286:         * iterate propagating register/variable synchrony
                    287:         *      forward until graph is complete
                    288:         */
                    289: loop2:
                    290:        change = 0;
                    291:        for(r = firstr; r != R; r = r->next)
                    292:                r->active = 0;
                    293:        synch(firstr, zbits);
                    294:        if(change)
                    295:                goto loop2;
                    296: 
                    297: 
                    298:        /*
                    299:         * pass 5
                    300:         * isolate regions
                    301:         * calculate costs (paint1)
                    302:         */
                    303:        r = firstr;
                    304:        if(r) {
                    305:                for(z=0; z<BITS; z++)
                    306:                        bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
                    307:                          ~(externs.b[z] | param.b[z] | addrs.b[z] | consts.b[z]);
                    308:                if(bany(&bit)) {
                    309:                        dummy.srcline = r->prog->lineno;
                    310:                        warn(&dummy, "used and not set: %B", bit);
                    311:                        if(opt('R') && !opt('w'))
                    312:                                print("used and not set: %B\n", bit);
                    313:                }
                    314:        }
                    315:        if(opt('R') && opt('v'))
                    316:                print("\nprop structure:\n");
                    317:        for(r = firstr; r != R; r = r->next)
                    318:                r->act = zbits;
                    319:        rgp = region;
                    320:        nregion = 0;
                    321:        for(r = firstr; r != R; r = r->next) {
                    322:                if(opt('R') && opt('v'))
                    323:                        print("%i\n     set = %B; rah = %B; cal = %B\n",
                    324:                                r->prog, r->set, r->refahead, r->calahead);
                    325:                for(z=0; z<BITS; z++)
                    326:                        bit.b[z] = r->set.b[z] &
                    327:                          ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
                    328:                if(bany(&bit)) {
                    329:                        dummy.srcline = r->prog->lineno;
                    330:                        warn(&dummy, "set and not used: %B", bit);
                    331:                        if(opt('R'))
                    332:                                print("set and not used: %B\n", bit);
                    333:                        excise(r);
                    334:                }
                    335:                for(z=0; z<BITS; z++)
                    336:                        bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
                    337:                while(bany(&bit)) {
                    338:                        i = bnum(bit);
                    339:                        rgp->enter = r;
                    340:                        rgp->varno = i;
                    341:                        change = 0;
                    342:                        if(opt('R') && opt('v'))
                    343:                                print("\n");
                    344:                        paint1(r, i);
                    345:                        bit.b[i/32] &= ~(1L<<(i%32));
                    346:                        if(change <= 0) {
                    347:                                if(opt('R'))
                    348:                                        print("%L$%d: %B\n",
                    349:                                                r->prog->lineno, change, blsh(i));
                    350:                                continue;
                    351:                        }
                    352:                        rgp->cost = change;
                    353:                        nregion++;
                    354:                        if(nregion >= NRGN) {
                    355:                                warn(ZeroN, "too many regions");
                    356:                                goto brk;
                    357:                        }
                    358:                        rgp++;
                    359:                }
                    360:        }
                    361: brk:
                    362:        qsort(region, nregion, sizeof(region[0]), rcmp);
                    363: 
                    364:        /*
                    365:         * pass 6
                    366:         * determine used registers (paint2)
                    367:         * replace code (paint3)
                    368:         */
                    369:        rgp = region;
                    370:        for(i=0; i<nregion; i++) {
                    371:                bit = blsh(rgp->varno);
                    372:                vreg = paint2(rgp->enter, rgp->varno);
                    373:                vreg = allreg(vreg, rgp);
                    374:                if(opt('R')) {
                    375:                        if(rgp->regno >= Nreg)
                    376:                                print("%L$%d F%d: %B\n",
                    377:                                        rgp->enter->prog->lineno,
                    378:                                        rgp->cost,
                    379:                                        rgp->regno-Nreg,
                    380:                                        bit);
                    381:                        else
                    382:                                print("%L$%d R%d: %B\n",
                    383:                                        rgp->enter->prog->lineno,
                    384:                                        rgp->cost,
                    385:                                        rgp->regno,
                    386:                                        bit);
                    387:                }
                    388:                if(rgp->regno != 0)
                    389:                        paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
                    390:                rgp++;
                    391:        }
                    392:        /*
                    393:         * pass 7
                    394:         * peep-hole on basic block
                    395:         */
                    396:        if(!opt('R') || opt('P'))
                    397:                peep();
                    398: 
                    399:        /*
                    400:         * pass 8
                    401:         * recalculate pc
                    402:         */
                    403:        val = initpc;
                    404:        for(r = firstr; r != R; r = r1) {
                    405:                r->pc = val;
                    406:                p = r->prog;
                    407:                r1 = r->next;
                    408:                p1 = P;
                    409:                if(r1 != R)
                    410:                        p1 = r1->prog;
                    411: 
                    412:                while(p != p1) {
                    413:                        switch(p->op) {
                    414:                        default:
                    415:                                p->pc = val++;
                    416: 
                    417:                        case ADATA:
                    418:                        case ADYNT:
                    419:                        case AINIT:
                    420:                        case AGLOBL:
                    421:                        case ANAME:
                    422:                        case ANOP:
                    423:                                p = p->next;
                    424:                        }
                    425:                }
                    426:        }
                    427:        pc = val;
                    428: 
                    429:        /*
                    430:         * last pass
                    431:         * fix up branches
                    432:         * free aux structures
                    433:         */
                    434:        if(opt('R'))
                    435:                if(bany(&addrs))
                    436:                        print("addrs: %B\n", addrs);
                    437: 
                    438:        r1 = 0; /* set */
                    439:        for(r = firstr; r != R; r = r->next) {
                    440:                p = r->prog;
                    441:                if(p->dst.type == A_BRANCH)
                    442:                        p->dst.ival = r->s2->pc;
                    443:                r1 = r;
                    444:        }
                    445:        for(p = firstr->prog; p && p->next; p = p->next)
                    446:                while(p->next && p->next->op == ANOP)
                    447:                        p->next = p->next->next;
                    448: 
                    449:        if(r1 != R) {
                    450:                r1->next = freer;
                    451:                freer = firstr;
                    452:        }
                    453: }
                    454: 
                    455: /*
                    456:  * add mov b,rn
                    457:  * just after r
                    458:  */
                    459: void
                    460: addmove(Reg *r, int bn, int rn, int f)
                    461: {
                    462:        Inst *p, *p1;
                    463:        Adres *a;
                    464:        Var *v;
                    465: 
                    466:        if(r->prog->op == AJMPL && r->next) {
                    467:                p1 = r->next->prog;
                    468:                if(p1->dst.type == A_REG && p1->dst.reg == RegSP)
                    469:                        r = r->next;
                    470:        }
                    471: 
                    472:        p1 = ai();
                    473:        *p1 = zprog;
                    474:        p = r->prog;
                    475: 
                    476:        p1->next = p->next;
                    477:        p->next = p1;
                    478:        p1->lineno = p->lineno;
                    479: 
                    480:        v = var + bn;
                    481: 
                    482:        a = &p1->dst;
                    483:        a->sym = v->sym;
                    484:        a->class = v->class;
                    485:        a->ival = v->ival;
                    486:        a->etype = v->etype;
                    487:        a->type = A_INDREG;
                    488:        if(a->etype == TARRAY || a->sym == ZeroS)
                    489:                a->type = A_CONST;
                    490: 
                    491:        p1->op = AMOVW;
                    492:        if(v->etype == TCHAR)
                    493:                p1->op = AMOVBU;
                    494:        if(v->etype == TSINT || v->etype == TSUINT)
                    495:                p1->op = AMOVH;
                    496:        if(v->etype == TFLOAT)
                    497:                p1->op = AFMOVD;
                    498: 
                    499:        p1->src1.type = A_REG;
                    500:        p1->src1.reg = rn;
                    501:        if(rn >= Nreg) {
                    502:                p1->src1.type = A_FREG;
                    503:                p1->src1.reg = rn-Nreg;
                    504:        }
                    505:        if(!f) {
                    506:                p1->src1 = *a;
                    507:                *a = zprog.src1;
                    508:                a->type = A_REG;
                    509:                a->reg = rn;
                    510:                if(rn >= Nreg) {
                    511:                        a->type = A_FREG;
                    512:                        a->reg = rn-Nreg;
                    513:                }
                    514:                if(v->etype == TCHAR)
                    515:                        p1->op = AMOVBU;
                    516:                if(v->etype == TSUINT)
                    517:                        p1->op = AMOVHU;
                    518:        }
                    519:        if(opt('R'))
                    520:                print("%i%|.a%i\n", p, COL1, p1);
                    521: }
                    522: 
                    523: Bits
                    524: mkvar(Adres *a, int docon)
                    525: {
                    526:        Var *v;
                    527:        int i, t, n, et, z;
                    528:        long o;
                    529:        Bits bit;
                    530:        Sym *s;
                    531: 
                    532:        t = a->type;
                    533:        if(t == A_REG && a->reg != Nreg)
                    534:                regbits |= RtoB(a->reg);
                    535:        if(t == A_FREG && a->reg != Nreg)
                    536:                regbits |= FtoB(a->reg);
                    537:        s = a->sym;
                    538:        o = a->ival;
                    539:        et = a->etype;
                    540:        if(s == ZeroS) {
                    541:                if(t != A_CONST || !docon || a->reg != Nreg)
                    542:                        goto none;
                    543:                et = TINT;
                    544:        }
                    545:        if(t == A_CONST) {
                    546:                if(s == ZeroS && sval(o))
                    547:                        goto none;
                    548:        }
                    549: 
                    550:        if(s && s->name[0] == '.' && et == TFLOAT)
                    551:                goto none;
                    552: 
                    553:        n = a->class;
                    554:        v = var;
                    555:        for(i=0; i<nvar; i++) {
                    556:                if(s == v->sym)
                    557:                if(n == v->class)
                    558:                if(o == v->ival)
                    559:                        goto out;
                    560:                v++;
                    561:        }
                    562:        if(nvar >= NVAR) {
                    563:                if(s)
                    564:                warn(ZeroN, "variable not optimized: %s", s->name);
                    565:                goto none;
                    566:        }
                    567:        i = nvar;
                    568:        nvar++;
                    569:        v = &var[i];
                    570:        v->sym = s;
                    571:        v->ival = o;
                    572:        v->etype = et;
                    573:        v->class = n;
                    574:        if(opt('R'))
                    575:                print("bit=%2d et=%2d %a\n", i, et, a);
                    576: out:
                    577:        bit = blsh(i);
                    578:        if(n == External || n == Internal || n == Global)
                    579:                for(z=0; z<BITS; z++)
                    580:                        externs.b[z] |= bit.b[z];
                    581:        if(n == Parameter)
                    582:                for(z=0; z<BITS; z++)
                    583:                        param.b[z] |= bit.b[z];
                    584:        if(v->etype != et || !(MSCALAR&(1<<et)))        /* funny punning */
                    585:                for(z=0; z<BITS; z++)
                    586:                        addrs.b[z] |= bit.b[z];
                    587:        if(t == A_CONST) {
                    588:                if(s == ZeroS) {
                    589:                        for(z=0; z<BITS; z++)
                    590:                                consts.b[z] |= bit.b[z];
                    591:                        return bit;
                    592:                }
                    593:                if(et != TARRAY)
                    594:                        for(z=0; z<BITS; z++)
                    595:                                addrs.b[z] |= bit.b[z];
                    596:                for(z=0; z<BITS; z++)
                    597:                        param.b[z] |= bit.b[z];
                    598:                return bit;
                    599:        }
                    600:        if(t == A_INDREG)
                    601:                return bit;
                    602: 
                    603: none:
                    604:        return zbits;
                    605: }
                    606: 
                    607: void
                    608: prop(Reg *r, Bits ref, Bits cal)
                    609: {
                    610:        Reg *r1, *r2;
                    611:        int z;
                    612: 
                    613:        for(r1 = r; r1 != R; r1 = r1->p1) {
                    614:                for(z=0; z<BITS; z++) {
                    615:                        ref.b[z] |= r1->refahead.b[z];
                    616:                        if(ref.b[z] != r1->refahead.b[z]) {
                    617:                                r1->refahead.b[z] = ref.b[z];
                    618:                                change++;
                    619:                        }
                    620:                        cal.b[z] |= r1->calahead.b[z];
                    621:                        if(cal.b[z] != r1->calahead.b[z]) {
                    622:                                r1->calahead.b[z] = cal.b[z];
                    623:                                change++;
                    624:                        }
                    625:                }
                    626:                switch(r1->prog->op) {
                    627:                case AJMPL:
                    628:                        for(z=0; z<BITS; z++) {
                    629:                                cal.b[z] |= ref.b[z] | externs.b[z];
                    630:                                ref.b[z] = 0;
                    631:                        }
                    632:                        break;
                    633: 
                    634:                case ATEXT:
                    635:                        for(z=0; z<BITS; z++) {
                    636:                                cal.b[z] = 0;
                    637:                                ref.b[z] = 0;
                    638:                        }
                    639:                        break;
                    640: 
                    641:                case ARETURN:
                    642:                        for(z=0; z<BITS; z++) {
                    643:                                cal.b[z] = externs.b[z];
                    644:                                ref.b[z] = 0;
                    645:                        }
                    646:                }
                    647:                for(z=0; z<BITS; z++) {
                    648:                        ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
                    649:                                r1->use1.b[z] | r1->use2.b[z];
                    650:                        cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
                    651:                        r1->refbehind.b[z] = ref.b[z];
                    652:                        r1->calbehind.b[z] = cal.b[z];
                    653:                }
                    654:                if(r1->active)
                    655:                        break;
                    656:                r1->active = 1;
                    657:        }
                    658:        for(; r != r1; r = r->p1)
                    659:                for(r2 = r->p2; r2 != R; r2 = r2->p2next)
                    660:                        prop(r2, r->refbehind, r->calbehind);
                    661: }
                    662: 
                    663: int
                    664: loopit(Reg *r)
                    665: {
                    666:        Reg *r1;
                    667:        int l, m;
                    668: 
                    669:        l = 0;
                    670:        r->active = 1;
                    671:        r->loop = 0;
                    672:        if(r1 = r->s1)
                    673:        switch(r1->active) {
                    674:        case 0:
                    675:                l += loopit(r1);
                    676:                break;
                    677:        case 1:
                    678:                l += LOOP;
                    679:                r1->loop += LOOP;
                    680:        }
                    681:        if(r1 = r->s2)
                    682:        switch(r1->active) {
                    683:        case 0:
                    684:                l += loopit(r1);
                    685:                break;
                    686:        case 1:
                    687:                l += LOOP;
                    688:                r1->loop += LOOP;
                    689:        }
                    690:        r->active = 2;
                    691:        m = r->loop;
                    692:        r->loop = l + 1;
                    693:        return l - m;
                    694: }
                    695: 
                    696: void
                    697: synch(Reg *r, Bits dif)
                    698: {
                    699:        Reg *r1;
                    700:        int z;
                    701: 
                    702:        for(r1 = r; r1 != R; r1 = r1->s1) {
                    703:                for(z=0; z<BITS; z++) {
                    704:                        dif.b[z] = (dif.b[z] &
                    705:                                ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
                    706:                                        r1->set.b[z] | r1->regdiff.b[z];
                    707:                        if(dif.b[z] != r1->regdiff.b[z]) {
                    708:                                r1->regdiff.b[z] = dif.b[z];
                    709:                                change++;
                    710:                        }
                    711:                }
                    712:                if(r1->active)
                    713:                        break;
                    714:                r1->active = 1;
                    715:                for(z=0; z<BITS; z++)
                    716:                        dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
                    717:                if(r1->s2 != R)
                    718:                        synch(r1->s2, dif);
                    719:        }
                    720: }
                    721: 
                    722: ulong
                    723: allreg(ulong b, Rgn *r)
                    724: {
                    725:        Var *v;
                    726:        int i;
                    727: 
                    728:        v = var + r->varno;
                    729:        r->regno = 0;
                    730:        switch(v->etype) {
                    731: 
                    732:        default:
                    733:                diag(ZeroN, "unknown etype %d/%d", bitno(b), v->etype);
                    734:                break;
                    735: 
                    736:        case TCHAR:
                    737:        case TSINT:
                    738:        case TSUINT:
                    739:        case TINT:
                    740:        case TUINT:
                    741:        case TIND:
                    742:        case TARRAY:
                    743:                i = BtoR(~b);
                    744:                if(i && r->cost > 0) {
                    745:                        r->regno = i;
                    746:                        return RtoB(i);
                    747:                }
                    748:                break;
                    749: 
                    750:        case TFLOAT:
                    751:                i = BtoF(~b);
                    752:                if(i && r->cost > 0) {
                    753:                        r->regno = i+Nreg;
                    754:                        return FtoB(i);
                    755:                }
                    756:                break;
                    757:        }
                    758:        return 0;
                    759: }
                    760: 
                    761: void
                    762: paint1(Reg *r, int bn)
                    763: {
                    764:        Reg *r1;
                    765:        Inst *p;
                    766:        int z;
                    767:        ulong bb;
                    768: 
                    769:        z = bn/32;
                    770:        bb = 1L<<(bn%32);
                    771:        if(r->act.b[z] & bb)
                    772:                return;
                    773:        for(;;) {
                    774:                if(!(r->refbehind.b[z] & bb))
                    775:                        break;
                    776:                r1 = r->p1;
                    777:                if(r1 == R)
                    778:                        break;
                    779:                if(!(r1->refahead.b[z] & bb))
                    780:                        break;
                    781:                if(r1->act.b[z] & bb)
                    782:                        break;
                    783:                r = r1;
                    784:        }
                    785: 
                    786:        if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
                    787:                change -= CLOAD * r->loop;
                    788:                if(opt('R') && opt('v'))
                    789:                        print("%d%i%|ld %B $%d\n", r->loop,
                    790:                                r->prog, COL1, blsh(bn), change);
                    791:        }
                    792:        for(;;) {
                    793:                r->act.b[z] |= bb;
                    794:                p = r->prog;
                    795: 
                    796:                if(r->use1.b[z] & bb) {
                    797:                        change += CREF * r->loop;
                    798:                        if(p->dst.type == A_FREG && p->op == AMOVW)
                    799:                                change = -CINF;         /* cant go Rreg to Freg */
                    800:                        if(opt('R') && opt('v'))
                    801:                                print("%d%i%|u1 %B $%d\n", r->loop,
                    802:                                        p, COL1, blsh(bn), change);
                    803:                }
                    804: 
                    805:                if((r->use2.b[z]|r->set.b[z]) & bb) {
                    806:                        change += CREF * r->loop;
                    807:                        if(p->src1.type == A_FREG && p->op == AMOVW)
                    808:                                change = -CINF;         /* cant go Rreg to Freg */
                    809:                        if(opt('R') && opt('v'))
                    810:                                print("%d%i%|u2 %B $%d\n", r->loop,
                    811:                                        p, COL1, blsh(bn), change);
                    812:                }
                    813: 
                    814:                if(STORE(r) & r->regdiff.b[z] & bb) {
                    815:                        change -= CLOAD * r->loop;
                    816:                        if(opt('R') && opt('v'))
                    817:                                print("%d%i%|st %B $%d\n", r->loop,
                    818:                                        p, COL1, blsh(bn), change);
                    819:                }
                    820: 
                    821:                if(r->refbehind.b[z] & bb)
                    822:                        for(r1 = r->p2; r1 != R; r1 = r1->p2next)
                    823:                                if(r1->refahead.b[z] & bb)
                    824:                                        paint1(r1, bn);
                    825: 
                    826:                if(!(r->refahead.b[z] & bb))
                    827:                        break;
                    828:                r1 = r->s2;
                    829:                if(r1 != R)
                    830:                        if(r1->refbehind.b[z] & bb)
                    831:                                paint1(r1, bn);
                    832:                r = r->s1;
                    833:                if(r == R)
                    834:                        break;
                    835:                if(r->act.b[z] & bb)
                    836:                        break;
                    837:                if(!(r->refbehind.b[z] & bb))
                    838:                        break;
                    839:        }
                    840: }
                    841: 
                    842: ulong
                    843: paint2(Reg *r, int bn)
                    844: {
                    845:        Reg *r1;
                    846:        int z;
                    847:        ulong bb, vreg;
                    848: 
                    849:        z = bn/32;
                    850:        bb = 1L << (bn%32);
                    851:        vreg = regbits;
                    852:        if(!(r->act.b[z] & bb))
                    853:                return vreg;
                    854:        for(;;) {
                    855:                if(!(r->refbehind.b[z] & bb))
                    856:                        break;
                    857:                r1 = r->p1;
                    858:                if(r1 == R)
                    859:                        break;
                    860:                if(!(r1->refahead.b[z] & bb))
                    861:                        break;
                    862:                if(!(r1->act.b[z] & bb))
                    863:                        break;
                    864:                r = r1;
                    865:        }
                    866:        for(;;) {
                    867:                r->act.b[z] &= ~bb;
                    868: 
                    869:                vreg |= r->regu;
                    870: 
                    871:                if(r->refbehind.b[z] & bb)
                    872:                        for(r1 = r->p2; r1 != R; r1 = r1->p2next)
                    873:                                if(r1->refahead.b[z] & bb)
                    874:                                        vreg |= paint2(r1, bn);
                    875: 
                    876:                if(!(r->refahead.b[z] & bb))
                    877:                        break;
                    878:                r1 = r->s2;
                    879:                if(r1 != R)
                    880:                        if(r1->refbehind.b[z] & bb)
                    881:                                vreg |= paint2(r1, bn);
                    882:                r = r->s1;
                    883:                if(r == R)
                    884:                        break;
                    885:                if(!(r->act.b[z] & bb))
                    886:                        break;
                    887:                if(!(r->refbehind.b[z] & bb))
                    888:                        break;
                    889:        }
                    890:        return vreg;
                    891: }
                    892: 
                    893: void
                    894: paint3(Reg *r, int bn, long rb, int rn)
                    895: {
                    896:        Reg *r1;
                    897:        Inst *p;
                    898:        int z;
                    899:        ulong bb;
                    900: 
                    901:        z = bn/32;
                    902:        bb = 1L << (bn%32);
                    903:        if(r->act.b[z] & bb)
                    904:                return;
                    905:        for(;;) {
                    906:                if(!(r->refbehind.b[z] & bb))
                    907:                        break;
                    908:                r1 = r->p1;
                    909:                if(r1 == R)
                    910:                        break;
                    911:                if(!(r1->refahead.b[z] & bb))
                    912:                        break;
                    913:                if(r1->act.b[z] & bb)
                    914:                        break;
                    915:                r = r1;
                    916:        }
                    917: 
                    918:        if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
                    919:                addmove(r, bn, rn, 0);
                    920:        for(;;) {
                    921:                r->act.b[z] |= bb;
                    922:                p = r->prog;
                    923: 
                    924:                if(r->use1.b[z] & bb) {
                    925:                        if(opt('R'))
                    926:                                print("%i", p);
                    927:                        addreg(&p->src1, rn);
                    928:                        if(opt('R'))
                    929:                                print("%|.c%i\n", COL1, p);
                    930:                }
                    931:                if((r->use2.b[z]|r->set.b[z]) & bb) {
                    932:                        if(opt('R'))
                    933:                                print("%i", p);
                    934:                        addreg(&p->dst, rn);
                    935:                        if(opt('R'))
                    936:                                print("%|.c%i\n", COL1, p);
                    937:                }
                    938: 
                    939:                if(STORE(r) & r->regdiff.b[z] & bb)
                    940:                        addmove(r, bn, rn, 1);
                    941:                r->regu |= rb;
                    942: 
                    943:                if(r->refbehind.b[z] & bb)
                    944:                        for(r1 = r->p2; r1 != R; r1 = r1->p2next)
                    945:                                if(r1->refahead.b[z] & bb)
                    946:                                        paint3(r1, bn, rb, rn);
                    947: 
                    948:                if(!(r->refahead.b[z] & bb))
                    949:                        break;
                    950:                r1 = r->s2;
                    951:                if(r1 != R)
                    952:                        if(r1->refbehind.b[z] & bb)
                    953:                                paint3(r1, bn, rb, rn);
                    954:                r = r->s1;
                    955:                if(r == R)
                    956:                        break;
                    957:                if(r->act.b[z] & bb)
                    958:                        break;
                    959:                if(!(r->refbehind.b[z] & bb))
                    960:                        break;
                    961:        }
                    962: }
                    963: 
                    964: void
                    965: addreg(Adres *a, int rn)
                    966: {
                    967:        a->sym = 0;
                    968:        a->type = A_REG;
                    969:        a->class = 0;
                    970:        a->reg = rn;
                    971:        if(rn >= Nreg) {
                    972:                a->type = A_FREG;
                    973:                a->reg = rn-Nreg;
                    974:        }
                    975: }
                    976: 
                    977: /*
                    978:  *     bit     reg
                    979:  *     0       R9
                    980:  *     1       R10
                    981:  *     ...     ...
                    982:  *     4       R13
                    983:  *     5       R16
                    984:  *     ...     ...
                    985:  *     20      R31
                    986:  */
                    987: long
                    988: RtoB(int r)
                    989: {
                    990: 
                    991:        if(r >= 9 && r <= 13)
                    992:                return 1L << (r-9);
                    993:        if(r >= 16 && r <= 31)
                    994:                return 1L << (r-11);
                    995:        return 0;
                    996: }
                    997: 
                    998: int
                    999: BtoR(long b)
                   1000: {
                   1001:        int r;
                   1002: 
                   1003:        b &= 0x001fffffL;
                   1004:        if(b == 0)
                   1005:                return 0;
                   1006:        r = bitno(b) + 9;
                   1007:        if(r >= 14)
                   1008:                r += 2;
                   1009:        return r;
                   1010: }
                   1011: 
                   1012: /*
                   1013:  *     bit     reg
                   1014:  *     22      F4
                   1015:  *     23      F6
                   1016:  *     ...     ...
                   1017:  *     31      F22
                   1018:  */
                   1019: long
                   1020: FtoB(int f)
                   1021: {
                   1022: 
                   1023:        if(f < 4 || f > 22 || (f&1))
                   1024:                return 0;
                   1025:        return 1L << (f/2 + 20);
                   1026: }
                   1027: 
                   1028: BtoF(long b)
                   1029: {
                   1030: 
                   1031:        b &= 0xffc00000L;
                   1032:        if(b == 0)
                   1033:                return 0;
                   1034:        return bitno(b)*2 - 40;
                   1035: }
                   1036: 
                   1037: int
                   1038: bany(Bits *a)
                   1039: {
                   1040:        int i;
                   1041: 
                   1042:        for(i=0; i<BITS; i++)
                   1043:                if(a->b[i])
                   1044:                        return 1;
                   1045:        return 0;
                   1046: }
                   1047: 
                   1048: int
                   1049: bnum(Bits a)
                   1050: {
                   1051:        int i;
                   1052:        long b;
                   1053: 
                   1054:        for(i=0; i<BITS; i++)
                   1055:                if(b = a.b[i])
                   1056:                        return 32*i + bitno(b);
                   1057:        diag(ZeroN, "bad in bnum");
                   1058:        return 0;
                   1059: }
                   1060: 
                   1061: Bits
                   1062: blsh(int n)
                   1063: {
                   1064:        Bits c;
                   1065: 
                   1066:        c = zbits;
                   1067:        c.b[n/32] = 1L << (n%32);
                   1068:        return c;
                   1069: }
                   1070: 
                   1071: int
                   1072: Bconv(void *o, Fconv *f)
                   1073: {
                   1074:        char str[128], ss[128], *s;
                   1075:        Bits bits;
                   1076:        int i;
                   1077: 
                   1078:        str[0] = 0;
                   1079:        bits = *(Bits*)o;
                   1080:        while(bany(&bits)) {
                   1081:                i = bnum(bits);
                   1082:                if(str[0])
                   1083:                        strcat(str, " ");
                   1084:                if(var[i].sym == ZeroS) {
                   1085:                        sprint(ss, "$%ld", var[i].ival);
                   1086:                        s = ss;
                   1087:                } else
                   1088:                        s = var[i].sym->name;
                   1089:                if(strlen(str) + strlen(s) + 1 >= 128)
                   1090:                        break;
                   1091:                strcat(str, s);
                   1092:                bits.b[i/32] &= ~(1L << (i%32));
                   1093:        }
                   1094:        strconv(str, f);
                   1095:        return sizeof(bits);
                   1096: }
                   1097: 
                   1098: int
                   1099: bitno(long b)
                   1100: {
                   1101:        int i;
                   1102: 
                   1103:        for(i=0; i<32; i++)
                   1104:                if(b & (1L<<i))
                   1105:                        return i;
                   1106:        diag(ZeroN, "bad in bitno");
                   1107:        return 0;
                   1108: }

unix.superglobalmegacorp.com

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