Annotation of lucent/sys/src/alef/k/peep.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: void
                     10: peep(void)
                     11: {
                     12:        Reg *r, *r1, *r2;
                     13:        Inst *p;
                     14:        int t;
                     15: /*
                     16:  * complete R structure
                     17:  */
                     18:        t = 0;
                     19:        for(r=firstr; r!=R; r=r1) {
                     20:                r1 = r->next;
                     21:                if(r1 == R)
                     22:                        break;
                     23:                p = r->prog->next;
                     24:                while(p != r1->prog)
                     25:                switch(p->op) {
                     26:                default:
                     27:                        r2 = rega();
                     28:                        r->next = r2;
                     29:                        r2->next = r1;
                     30: 
                     31:                        r2->prog = p;
                     32:                        r2->p1 = r;
                     33:                        r->s1 = r2;
                     34:                        r2->s1 = r1;
                     35:                        r1->p1 = r2;
                     36: 
                     37:                        r = r2;
                     38:                        t++;
                     39: 
                     40:                case ADATA:
                     41:                case ADYNT:
                     42:                case AINIT:
                     43:                case AGLOBL:
                     44:                case ANAME:
                     45:                        p = p->next;
                     46:                }
                     47:        }
                     48: 
                     49: loop1:
                     50:        t = 0;
                     51:        for(r=firstr; r!=R; r=r->next) {
                     52:                p = r->prog;
                     53:                if(p->op == AMOVW || p->op == AFMOVF || p->op == AFMOVD)
                     54:                if(regtyp(&p->dst)) {
                     55:                        if(regtyp(&p->src1))
                     56:                        if(p->src1.type == p->dst.type) {
                     57:                                if(copyprop(r)) {
                     58:                                        excise(r);
                     59:                                        t++;
                     60:                                } else
                     61:                                if(subprop(r) && copyprop(r)) {
                     62:                                        excise(r);
                     63:                                        t++;
                     64:                                }
                     65:                        }
                     66:                        if(regzer(&p->src1))
                     67:                        if(p->dst.type == A_REG) {
                     68:                                p->src1.type = A_REG;
                     69:                                p->src1.reg = 0;
                     70:                                if(copyprop(r)) {
                     71:                                        excise(r);
                     72:                                        t++;
                     73:                                } else
                     74:                                if(subprop(r) && copyprop(r)) {
                     75:                                        excise(r);
                     76:                                        t++;
                     77:                                }
                     78:                        }
                     79:                }
                     80:        }
                     81:        if(t)
                     82:                goto loop1;
                     83: }
                     84: 
                     85: void
                     86: excise(Reg *r)
                     87: {
                     88:        Inst *p;
                     89: 
                     90:        p = r->prog;
                     91:        p->op = ANOP;
                     92:        p->src1 = zprog.src1;
                     93:        p->dst = zprog.dst;
                     94:        p->reg = zprog.reg; /**/
                     95: }
                     96: 
                     97: Reg*
                     98: uniqp(Reg *r)
                     99: {
                    100:        Reg *r1;
                    101: 
                    102:        r1 = r->p1;
                    103:        if(r1 == R) {
                    104:                r1 = r->p2;
                    105:                if(r1 == R || r1->p2next != R)
                    106:                        return R;
                    107:        } else
                    108:                if(r->p2 != R)
                    109:                        return R;
                    110:        return r1;
                    111: }
                    112: 
                    113: Reg*
                    114: uniqs(Reg *r)
                    115: {
                    116:        Reg *r1;
                    117: 
                    118:        r1 = r->s1;
                    119:        if(r1 == R) {
                    120:                r1 = r->s2;
                    121:                if(r1 == R)
                    122:                        return R;
                    123:        } else
                    124:                if(r->s2 != R)
                    125:                        return R;
                    126:        return r1;
                    127: }
                    128: 
                    129: regzer(Adres *a)
                    130: {
                    131: 
                    132:        if(a->type == A_CONST)
                    133:                if(a->sym == ZeroS)
                    134:                        if(a->ival == 0)
                    135:                                return 1;
                    136:        if(a->type == A_REG)
                    137:                if(a->reg == 0)
                    138:                        return 1;
                    139:        return 0;
                    140: }
                    141: 
                    142: regtyp(Adres *a)
                    143: {
                    144: 
                    145:        if(a->type == A_REG) {
                    146:                if(a->reg != 0)
                    147:                        return 1;
                    148:                return 0;
                    149:        }
                    150:        if(a->type == A_FREG)
                    151:                return 1;
                    152:        return 0;
                    153: }
                    154: 
                    155: /*
                    156:  * the idea is to substitute
                    157:  * one register for another
                    158:  * from one MOV to another
                    159:  *     MOV     a, R0
                    160:  *     ADD     b, R0   / no use of R1
                    161:  *     MOV     R0, R1
                    162:  * would be converted to
                    163:  *     MOV     a, R1
                    164:  *     ADD     b, R1
                    165:  *     MOV     R1, R0
                    166:  * hopefully, then the former or latter MOV
                    167:  * will be eliminated by copy propagation.
                    168:  */
                    169: int
                    170: subprop(Reg *r0)
                    171: {
                    172:        Inst *p;
                    173:        Adres *v1, *v2;
                    174:        Reg *r;
                    175:        int t;
                    176: 
                    177:        p = r0->prog;
                    178:        v1 = &p->src1;
                    179:        if(!regtyp(v1))
                    180:                return 0;
                    181:        v2 = &p->dst;
                    182:        if(!regtyp(v2))
                    183:                return 0;
                    184:        for(r=uniqp(r0); r!=R; r=uniqp(r)) {
                    185:                if(uniqs(r) == R)
                    186:                        break;
                    187:                p = r->prog;
                    188:                switch(p->op) {
                    189:                case AJMPL:
                    190:                        return 0;
                    191: 
                    192:                case AADD:
                    193:                case ASUB:
                    194:                case ASLL:
                    195:                case ASRL:
                    196:                case ASRA:
                    197:                case AOR:
                    198:                case AAND:
                    199:                case AXOR:
                    200:                case AMUL:
                    201:                case ADIV:
                    202:                case ADIVL:
                    203:                case AMOD:
                    204:                case AMODL:
                    205: 
                    206:                case AFADDD:
                    207:                case AFADDF:
                    208:                case AFSUBD:
                    209:                case AFSUBF:
                    210:                case AFMULD:
                    211:                case AFMULF:
                    212:                case AFDIVD:
                    213:                case AFDIVF:
                    214:                        if(p->dst.type == v1->type)
                    215:                        if(p->dst.reg == v1->reg) {
                    216:                                if(p->reg == Nreg)
                    217:                                        p->reg = p->dst.reg;
                    218:                                goto gotit;
                    219:                        }
                    220:                        break;
                    221: 
                    222:                case AFMOVF:
                    223:                case AFMOVD:
                    224:                case AMOVW:
                    225:                        if(p->dst.type == v1->type)
                    226:                        if(p->dst.reg == v1->reg)
                    227:                                goto gotit;
                    228:                        break;
                    229:                }
                    230:                if(copyau(&p->src1, v2) ||
                    231:                   copyau1(p, v2) ||
                    232:                   copyau(&p->dst, v2))
                    233:                        break;
                    234:                if(copysub(&p->src1, v1, v2, 0) ||
                    235:                   copysub1(p, v1, v2, 0) ||
                    236:                   copysub(&p->dst, v1, v2, 0))
                    237:                        break;
                    238:        }
                    239:        return 0;
                    240: 
                    241: gotit:
                    242:        copysub(&p->dst, v1, v2, 1);
                    243:        if(opt('P')) {
                    244:                print("gotit: %a->%a\n%i", v1, v2, r->prog);
                    245:                if(p->src1.type == v2->type)
                    246:                        print(" excise");
                    247:                print("\n");
                    248:        }
                    249:        for(r=uniqs(r); r!=r0; r=uniqs(r)) {
                    250:                p = r->prog;
                    251:                copysub(&p->src1, v1, v2, 1);
                    252:                copysub1(p, v1, v2, 1);
                    253:                copysub(&p->dst, v1, v2, 1);
                    254:                if(opt('P'))
                    255:                        print("%i\n", r->prog);
                    256:        }
                    257:        t = v1->reg;
                    258:        v1->reg = v2->reg;
                    259:        v2->reg = t;
                    260:        if(opt('P'))
                    261:                print("%i last\n", r->prog);
                    262:        return 1;
                    263: }
                    264: 
                    265: /*
                    266:  * The idea is to remove redundant copies.
                    267:  *     v1->v2  F=0
                    268:  *     (use v2 s/v2/v1/)*
                    269:  *     set v1  F=1
                    270:  *     use v2  return fail
                    271:  *     -----------------
                    272:  *     v1->v2  F=0
                    273:  *     (use v2 s/v2/v1/)*
                    274:  *     set v1  F=1
                    275:  *     set v2  return success
                    276:  */
                    277: int
                    278: copyprop(Reg *r0)
                    279: {
                    280:        Inst *p;
                    281:        Adres *v1, *v2;
                    282:        Reg *r;
                    283: 
                    284:        p = r0->prog;
                    285:        v1 = &p->src1;
                    286:        v2 = &p->dst;
                    287:        if(copyas(v1, v2))
                    288:                return 1;
                    289:        for(r=firstr; r!=R; r=r->next)
                    290:                r->active = 0;
                    291:        return copy1(v1, v2, r0->s1, 0);
                    292: }
                    293: 
                    294: copy1(Adres *v1, Adres *v2, Reg *r, int f)
                    295: {
                    296:        int t;
                    297:        Inst *p;
                    298: 
                    299:        if(r->active) {
                    300:                if(opt('P'))
                    301:                        print("act set; return 1\n");
                    302:                return 1;
                    303:        }
                    304:        r->active = 1;
                    305:        if(opt('P'))
                    306:                print("copy %a->%a f=%d\n", v1, v2, f);
                    307:        for(; r != R; r = r->s1) {
                    308:                p = r->prog;
                    309:                if(opt('P'))
                    310:                        print("%i", p);
                    311:                if(!f && uniqp(r) == R) {
                    312:                        f = 1;
                    313:                        if(opt('P'))
                    314:                                print("; merge; f=%d", f);
                    315:                }
                    316:                t = copyu(p, v2, A);
                    317:                switch(t) {
                    318:                case 2: /* rar, cant split */
                    319:                        if(opt('P'))
                    320:                                print("; %arar; return 0\n", v2);
                    321:                        return 0;
                    322: 
                    323:                case 3: /* set */
                    324:                        if(opt('P'))
                    325:                                print("; %aset; return 1\n", v2);
                    326:                        return 1;
                    327: 
                    328:                case 1: /* used, substitute */
                    329:                case 4: /* use and set */
                    330:                        if(f) {
                    331:                                if(!opt('P'))
                    332:                                        return 0;
                    333:                                if(t == 4)
                    334:                                        print("; %aused+set and f=%d; return 0\n", v2, f);
                    335:                                else
                    336:                                        print("; %aused and f=%d; return 0\n", v2, f);
                    337:                                return 0;
                    338:                        }
                    339:                        if(copyu(p, v2, v1)) {
                    340:                                if(opt('P'))
                    341:                                        print("; sub fail; return 0\n");
                    342:                                return 0;
                    343:                        }
                    344:                        if(opt('P'))
                    345:                                print("; sub%a/%a", v2, v1);
                    346:                        if(t == 4) {
                    347:                                if(opt('P'))
                    348:                                        print("; %aused+set; return 1\n", v2);
                    349:                                return 1;
                    350:                        }
                    351:                        break;
                    352:                }
                    353:                if(!f) {
                    354:                        t = copyu(p, v1, A);
                    355:                        if(!f && (t == 2 || t == 3 || t == 4)) {
                    356:                                f = 1;
                    357:                                if(opt('P'))
                    358:                                        print("; %aset and !f; f=%d", v1, f);
                    359:                        }
                    360:                }
                    361:                if(opt('P'))
                    362:                        print("\n");
                    363:                if(r->s2)
                    364:                        if(!copy1(v1, v2, r->s2, f))
                    365:                                return 0;
                    366:        }
                    367:        return 1;
                    368: }
                    369: 
                    370: /*
                    371:  * return
                    372:  * 1 if v only used (and substitute),
                    373:  * 2 if read-alter-rewrite
                    374:  * 3 if set
                    375:  * 4 if set and used
                    376:  * 0 otherwise (not touched)
                    377:  */
                    378: int
                    379: copyu(Inst *p, Adres *v, Adres *s)
                    380: {
                    381: 
                    382:        switch(p->op) {
                    383: 
                    384:        default:
                    385:                if(opt('P'))
                    386:                        print(" (???)");
                    387:                return 2;
                    388: 
                    389: 
                    390:        case ANOP:      /* read, write */
                    391:        case AMOVW:
                    392:        case AMOVH:
                    393:        case AMOVHU:
                    394:        case AMOVB:
                    395:        case AMOVBU:
                    396: 
                    397:        case AFMOVF:
                    398:        case AFMOVD:
                    399:        case AFMOVDW:
                    400:        case AFMOVWD:
                    401:        case AFMOVFW:
                    402:        case AFMOVWF:
                    403:        case AFMOVFD:
                    404:        case AFMOVDF:
                    405:                if(s != A) {
                    406:                        if(copysub(&p->src1, v, s, 1))
                    407:                                return 1;
                    408:                        if(!copyas(&p->dst, v))
                    409:                                if(copysub(&p->dst, v, s, 1))
                    410:                                        return 1;
                    411:                        return 0;
                    412:                }
                    413:                if(copyas(&p->dst, v)) {
                    414:                        if(copyau(&p->src1, v))
                    415:                                return 4;
                    416:                        return 3;
                    417:                }
                    418:                if(copyau(&p->src1, v))
                    419:                        return 1;
                    420:                if(copyau(&p->dst, v))
                    421:                        return 1;
                    422:                return 0;
                    423: 
                    424:        case AADD:      /* read read write */
                    425:        case ASUB:
                    426:        case ASLL:
                    427:        case ASRL:
                    428:        case ASRA:
                    429:        case AOR:
                    430:        case AAND:
                    431:        case AXOR:
                    432:        case AMUL:
                    433:        case ADIV:
                    434:        case ADIVL:
                    435:        case AMOD:
                    436:        case AMODL:
                    437: 
                    438:        case AFADDF:
                    439:        case AFADDD:
                    440:        case AFSUBF:
                    441:        case AFSUBD:
                    442:        case AFMULF:
                    443:        case AFMULD:
                    444:        case AFDIVF:
                    445:        case AFDIVD:
                    446:                if(s != A) {
                    447:                        if(copysub(&p->src1, v, s, 1))
                    448:                                return 1;
                    449:                        if(copysub1(p, v, s, 1))
                    450:                                return 1;
                    451:                        if(!copyas(&p->dst, v))
                    452:                                if(copysub(&p->dst, v, s, 1))
                    453:                                        return 1;
                    454:                        return 0;
                    455:                }
                    456:                if(copyas(&p->dst, v)) {
                    457:                        if(p->reg == Nreg)
                    458:                                p->reg = p->dst.reg;
                    459:                        if(copyau(&p->src1, v))
                    460:                                return 4;
                    461:                        if(copyau1(p, v))
                    462:                                return 4;
                    463:                        return 3;
                    464:                }
                    465:                if(copyau(&p->src1, v))
                    466:                        return 1;
                    467:                if(copyau1(p, v))
                    468:                        return 1;
                    469:                if(copyau(&p->dst, v))
                    470:                        return 1;
                    471:                return 0;
                    472: 
                    473:        case ABA:       /* no reference */
                    474:        case ABCC:
                    475:        case ABCS:
                    476:        case ABE:
                    477:        case ABG:
                    478:        case ABGE:
                    479:        case ABGU:
                    480:        case ABL:
                    481:        case ABLE:
                    482:        case ABLEU:
                    483:        case ABN:
                    484:        case ABNE:
                    485:        case ABNEG:
                    486:        case ABPOS:
                    487:        case ABVC:
                    488:        case ABVS:
                    489:        case AFBA:
                    490:        case AFBE:
                    491:        case AFBG:
                    492:        case AFBGE:
                    493:        case AFBL:
                    494:        case AFBLE:
                    495:        case AFBLG:
                    496:        case AFBN:
                    497:        case AFBNE:
                    498:        case AFBO:
                    499:        case AFBU:
                    500:        case AFBUE:
                    501:        case AFBUG:
                    502:        case AFBUGE:
                    503:        case AFBUL:
                    504:        case AFBULE:
                    505:                break;
                    506: 
                    507:        case ACMP:      /* read read */
                    508:        case AFCMPD:
                    509:        case AFCMPF:
                    510:                if(s != A) {
                    511:                        if(copysub(&p->src1, v, s, 1))
                    512:                                return 1;
                    513:                        return copysub(&p->dst, v, s, 1);
                    514:                }
                    515:                if(copyau(&p->src1, v))
                    516:                        return 1;
                    517:                if(copyau(&p->dst, v))
                    518:                        return 1;
                    519:                break;
                    520: 
                    521:        case AJMP:      /* funny */
                    522:                if(s != A) {
                    523:                        if(copysub(&p->dst, v, s, 1))
                    524:                                return 1;
                    525:                        return 0;
                    526:                }
                    527:                if(copyau(&p->dst, v))
                    528:                        return 1;
                    529:                return 0;
                    530: 
                    531:        case ARETURN:   /* funny */
                    532:                if(v->type == A_REG && v->reg == REGRET)
                    533:                        return 2;
                    534:                if(v->type == A_FREG && v->reg == FREGRET)
                    535:                        return 2;
                    536: 
                    537:        case AJMPL:     /* funny */
                    538:                if(v->type == A_REG) {
                    539:                        if(v->reg == Regspass)
                    540:                                return 2;
                    541:                        if(v->reg == RegSP)
                    542:                                return 2;
                    543:                }
                    544:                if(s != A) {
                    545:                        if(copysub(&p->dst, v, s, 1))
                    546:                                return 1;
                    547:                        return 0;
                    548:                }
                    549:                if(copyau(&p->dst, v))
                    550:                        return 4;
                    551:                return 3;
                    552: 
                    553:        case ATEXT:     /* funny */
                    554:                if(v->type == A_REG)
                    555:                        if(v->reg == Regspass)
                    556:                                return 3;
                    557:                return 0;
                    558:        }
                    559:        return 0;
                    560: }
                    561: 
                    562: int
                    563: a2type(Inst *p)
                    564: {
                    565: 
                    566:        switch(p->op) {
                    567:        case AADD:
                    568:        case ASUB:
                    569:        case ASLL:
                    570:        case ASRL:
                    571:        case ASRA:
                    572:        case AOR:
                    573:        case AAND:
                    574:        case AXOR:
                    575:        case AMUL:
                    576:        case ADIV:
                    577:        case ADIVL:
                    578:        case AMOD:
                    579:        case AMODL:
                    580:                return A_REG;
                    581: 
                    582:        case AFADDF:
                    583:        case AFADDD:
                    584:        case AFSUBF:
                    585:        case AFSUBD:
                    586:        case AFMULF:
                    587:        case AFMULD:
                    588:        case AFDIVF:
                    589:        case AFDIVD:
                    590:                return A_FREG;
                    591:        }
                    592:        return A_NONE;
                    593: }
                    594: 
                    595: /*
                    596:  * direct reference,
                    597:  * could be set/use depending on
                    598:  * semantics
                    599:  */
                    600: int
                    601: copyas(Adres *a, Adres *v)
                    602: {
                    603: 
                    604:        if(regtyp(v))
                    605:                if(a->type == v->type)
                    606:                if(a->reg == v->reg)
                    607:                        return 1;
                    608:        return 0;
                    609: }
                    610: 
                    611: /*
                    612:  * either direct or indirect
                    613:  */
                    614: int
                    615: copyau(Adres *a, Adres *v)
                    616: {
                    617: 
                    618:        if(copyas(a, v))
                    619:                return 1;
                    620:        if(v->type == A_REG)
                    621:                if(a->type == A_INDREG)
                    622:                        if(v->reg == a->reg)
                    623:                                return 1;
                    624:        return 0;
                    625: }
                    626: 
                    627: int
                    628: copyau1(Inst *p, Adres *v)
                    629: {
                    630: 
                    631:        if(regtyp(v))
                    632:                if(p->src1.type == v->type || p->dst.type == v->type)
                    633:                if(p->reg == v->reg) {
                    634:                        if(a2type(p) != v->type)
                    635:                                print("botch a2type %i\n", p);
                    636:                        return 1;
                    637:                }
                    638:        return 0;
                    639: }
                    640: 
                    641: /*
                    642:  * substitute s for v in a
                    643:  * return failure to substitute
                    644:  */
                    645: int
                    646: copysub(Adres *a, Adres *v, Adres *s, int f)
                    647: {
                    648: 
                    649:        if(f)
                    650:        if(copyau(a, v))
                    651:                a->reg = s->reg;
                    652:        return 0;
                    653: }
                    654: 
                    655: int
                    656: copysub1(Inst *p1, Adres *v, Adres *s, int f)
                    657: {
                    658: 
                    659:        if(f)
                    660:        if(copyau1(p1, v))
                    661:                p1->reg = s->reg;
                    662:        return 0;
                    663: }

unix.superglobalmegacorp.com

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