Annotation of lucent/sys/src/alef/k/regopt.c, revision 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.