Annotation of 43BSDTahoe/usr.bin/f77/f77.tahoe/f77pass1/regalloc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)regalloc.c 5.1 (Berkeley) 6/7/85";
                      9: #endif not lint
                     10: 
                     11: /*
                     12:  * regalloc.c
                     13:  *
                     14:  * Register optimization routines for f77 compiler, pass 1
                     15:  *
                     16:  * University of Utah CS Dept modification history:
                     17:  *
                     18:  * $History$
                     19:  * $Log:       regalloc.c,v $
                     20:  * Revision 1.4  86/02/12  15:29:16  rcs
                     21:  * 4.3 F77. C. Keating.
                     22:  * 
                     23:  * Revision 2.9  85/03/18  21:35:05  donn
                     24:  * Bob Corbett's hack to prevent conflicts between subroutine side effects
                     25:  * and register assignment.  Makes the code a lot worse...
                     26:  * 
                     27:  * Revision 2.8  85/02/22  02:14:08  donn
                     28:  * In code like 'x = foo(x)', alreg() would copy the memory version of the
                     29:  * variable 'x' into the register version after the assignment, clobbering
                     30:  * the result.  A small change to regwrite() seems to prevent this.
                     31:  * 
                     32:  * Revision 2.7  85/02/16  03:32:45  donn
                     33:  * Fixed a bug where the loop test and increment were having register
                     34:  * substitution performed twice, once in the environment of the current
                     35:  * loop and once in the environment of the containing loop.  If the
                     36:  * containing loop puts (say) the inner loop's index variable in register
                     37:  * but the inner loop does not, havoc results.
                     38:  * 
                     39:  * Revision 2.6  85/02/14  23:21:45  donn
                     40:  * Don't permit variable references of the form 'a(i)' to be put in register
                     41:  * if array 'a' is in common.  This is because there is no good way to
                     42:  * identify instances of this sort without getting confused with other
                     43:  * variables in the same common block which are in register.  Sigh.
                     44:  * 
                     45:  * Revision 2.5  85/01/11  21:08:00  donn
                     46:  * Made changes so that we pay attention to SAVE statements.  Added a new
                     47:  * gensetreturn() function to implement this.
                     48:  * 
                     49:  * Revision 2.4  84/09/03  22:37:28  donn
                     50:  * Changed the treatment of SKRETURN in alreg() so that all variables in
                     51:  * register, not just COMMON variables, get written out to memory before a
                     52:  * RETURN.  This was causing the return value of a function to get lost when
                     53:  * a RETURN was done from inside a loop (among other problems).
                     54:  * 
                     55:  * Revision 2.3  84/08/04  20:52:42  donn
                     56:  * Added fixes for EXTERNAL parameters from Jerry Berkman.
                     57:  * 
                     58:  * Revision 2.2  84/08/04  20:34:29  donn
                     59:  * Fixed a stupidity pointed out by Jerry Berkman -- the 'floats in register'
                     60:  * stuff applies if the TARGET is a VAX, not if the local machine is a VAX.
                     61:  * 
                     62:  * Revision 2.1  84/07/19  12:04:47  donn
                     63:  * Changed comment headers for UofU.
                     64:  * 
                     65:  * Revision 1.5  83/11/27  19:25:41  donn
                     66:  * Added REAL to the list of types which may appear in registers (VAXen only).
                     67:  * 
                     68:  * Revision 1.4  83/11/13  02:38:39  donn
                     69:  * Bug fixed in alreg()'s handling of computed goto's.  A '<=' in place of a
                     70:  * '<' led to core dumps when we walked off the end of the list of labels...
                     71:  * 
                     72:  * Revision 1.3  83/11/12  01:25:57  donn
                     73:  * Bug in redundant register assignment code, mistakenly carried over some old
                     74:  * code that sometimes rewound a slot pointer even when a redundant slot wasn't
                     75:  * deleted; this caused an infinite loop...  Seems to work now.
                     76:  * 
                     77:  * Revision 1.2  83/11/09  14:58:12  donn
                     78:  * Took out broken code dealing with redundant register initializations.
                     79:  * Couldn't see what to do about redundantly initializing a DO variable but
                     80:  * I did fix things so that an assignment from a register into the same
                     81:  * register is always deleted.
                     82:  * 
                     83:  */
                     84: 
                     85: #include "defs.h"
                     86: #include "optim.h"
                     87: 
                     88: #define LABTABSIZE 101
                     89: #define VARTABSIZE 1009
                     90: #define TABLELIMIT 12
                     91: 
                     92: #if TARGET==VAX || TARGET==TAHOE
                     93: #define MSKREGTYPES M(TYLOGICAL) | M(TYADDR) | M(TYSHORT) | M(TYLONG) | M(TYREAL)
                     94: #if TARGET==TAHOE
                     95: #define BUMPREALS      /* put floats last */
                     96: #endif
                     97: #else
                     98: #define MSKREGTYPES M(TYLOGICAL) | M(TYADDR) | M(TYSHORT) | M(TYLONG)
                     99: #endif
                    100: 
                    101: 
                    102: #define ISREGTYPE(x) ONEOF(x, MSKREGTYPES)
                    103: 
                    104: #define MSKVARS M(STGAUTO) | M(STGBSS) | M(STGINIT) | M(STGCONST) |\
                    105:                M(STGEQUIV) | M(STGARG) | M(STGCOMMON)
                    106: 
                    107: #define ISVAR(x) ((((expptr) x)->headblock.vclass == CLVAR || \
                    108:                        ((expptr) x)->headblock.vclass == CLUNKNOWN) \
                    109:                   && ONEOF(((expptr) x)->headblock.vstg, MSKVARS))
                    110: 
                    111: 
                    112: typedef
                    113:   struct regdata
                    114:     {
                    115:       field vstg;
                    116:       field vtype;
                    117:       int memno;
                    118:       int memoffset;
                    119:       int refs;
                    120:       Addrp stgp;
                    121:       unsigned isarrayarg : 1;
                    122:       unsigned istemp : 1;
                    123:       unsigned isset : 1;
                    124:       unsigned setfirst : 1;
                    125:     } REGDATA;
                    126: 
                    127: 
                    128: typedef
                    129:   struct labelnode
                    130:     {
                    131:       struct labelnode *link;
                    132:       int labelno;
                    133:     } LABELNODE;
                    134: 
                    135: 
                    136: 
                    137: typedef
                    138:   struct varnode
                    139:     {
                    140:       struct varnode *link;
                    141:       int memoffset;
                    142:       unsigned isset : 1;
                    143:       unsigned isused : 1;
                    144:       unsigned setfirst : 1;
                    145:       unsigned unusable : 1;
                    146:       int refs;
                    147:       Addrp stgp;
                    148:     } VARNODE;
                    149: 
                    150: 
                    151: typedef
                    152:   struct addrnode
                    153:     {
                    154:       struct addrnode *link;
                    155:       field vtype;
                    156:       field vstg;
                    157:       int memno;
                    158:       unsigned istemp : 1;
                    159:       unsigned isset : 1;
                    160:       unsigned loopset :1;
                    161:       unsigned freeuse : 1;
                    162:       unsigned mixedtype : 1;
                    163:       unsigned fixed : 1;
                    164:       int refs;
                    165:       struct addrnode *commonlink;
                    166:       VARNODE *varlist;
                    167:     } ADDRNODE;
                    168: 
                    169: 
                    170: typedef
                    171:   struct setnode
                    172:     {
                    173:       struct setnode *link;
                    174:       field vstg;
                    175:       int memno;
                    176:       int memoffset;
                    177:     } SETNODE;
                    178: 
                    179: 
                    180: typedef
                    181:   struct doqueue
                    182:     {
                    183:       struct doqueue *up, *down;
                    184:       Slotp dohead, doend;
                    185:       int nregvars;
                    186:       REGNODE *reg[MAXREGVAR];
                    187:     }  DOQUEUE;
                    188: 
                    189: LOCAL DOQUEUE *dqptr, *dqtop, *dqbottom;
                    190: 
                    191: 
                    192: LOCAL Slotp dohead;
                    193: LOCAL Slotp doend;
                    194: LOCAL Slotp newcode;
                    195: 
                    196: 
                    197: 
                    198: LOCAL LABELNODE *labeltable[LABTABSIZE];
                    199: LOCAL ADDRNODE *vartable[VARTABSIZE];
                    200: LOCAL ADDRNODE *commonvars;
                    201: LOCAL SETNODE *setlist;
                    202: LOCAL int topregvar;
                    203: LOCAL int toplcv;
                    204: LOCAL int allset;
                    205: LOCAL ADDRNODE *currentaddr;
                    206: LOCAL int loopcost;
                    207: LOCAL REGDATA *regtab[MAXREGVAR];
                    208: LOCAL REGDATA *rt[TABLELIMIT];
                    209: LOCAL int tabletop;
                    210: LOCAL int linearcode;
                    211: LOCAL int docount;
                    212: LOCAL int globalbranch;
                    213: LOCAL int commonunusable;
                    214: LOCAL int regdefined[MAXREGVAR];
                    215: LOCAL int memdefined[MAXREGVAR];
                    216: LOCAL int regaltered[MAXREGVAR];
                    217: 
                    218: 
                    219: 
                    220: LOCAL insertlabel(l)
                    221: int l;
                    222: 
                    223: {
                    224:   int key;
                    225:   LABELNODE *p;
                    226: 
                    227:   key = l % LABTABSIZE;
                    228:   for (p = labeltable[key]; p; p = p->link)
                    229:     if (p->labelno == l) return;
                    230:   p = labeltable[key];
                    231:   labeltable[key] = ALLOC(labelnode);
                    232:   labeltable[key]->link = p;
                    233:   labeltable[key]->labelno = l;
                    234:   return;
                    235: }
                    236: 
                    237: 
                    238: 
                    239: LOCAL int locallabel(l)
                    240: int l;
                    241: 
                    242: {
                    243:   int key;
                    244:   LABELNODE *p;
                    245: 
                    246:   key = l % LABTABSIZE;
                    247:   for (p = labeltable[key]; p; p = p->link)
                    248:     if (p->labelno == l) return YES;
                    249: 
                    250:   return NO;
                    251: }
                    252: 
                    253: 
                    254: 
                    255: LOCAL freelabtab()
                    256: 
                    257: {
                    258:   int i;
                    259:   LABELNODE *p, *q;
                    260: 
                    261:   for (i = 0; i < LABTABSIZE; i++)
                    262:     if (labeltable[i])
                    263:       {
                    264:        p = labeltable[i];
                    265:        labeltable[i] = NULL;
                    266:        while (p)
                    267:          {
                    268:            q = p->link;
                    269:            free(p);
                    270:            p = q;
                    271:          }
                    272:       }
                    273:   return;
                    274: }
                    275: 
                    276: 
                    277: 
                    278: LOCAL ADDRNODE *getaddr(ap)
                    279: Addrp ap;
                    280: 
                    281: {
                    282:   int key;
                    283:   field vstg;
                    284:   int memno;
                    285:   register ADDRNODE *q;
                    286:   ADDRNODE *q1;
                    287: 
                    288:   if (!ISVAR(ap))
                    289:     fatal("regalloc: bad data sent to getaddr");
                    290:   vstg = ap->vstg;
                    291:   memno = ap->memno;
                    292:   key = (256*vstg + memno) % VARTABSIZE;
                    293: 
                    294:   for (q = vartable[key]; q; q = q->link)
                    295:     if ((q->vstg == vstg) && (q->memno == memno)) 
                    296:       {
                    297:        if (ap->istemp) q->istemp = YES;
                    298:        if (ap->vtype != q->vtype)
                    299:          q->mixedtype = YES;
                    300:        if (!fixedaddress(ap))
                    301:          q->fixed = NO;
                    302:        return q;
                    303:       }
                    304: 
                    305:   q1 = vartable[key];
                    306:   vartable[key] = q = ALLOC(addrnode);
                    307:   q->link = q1;
                    308:   q->vstg = vstg;
                    309:   q->memno = memno;
                    310:   if (ap->istemp) q->istemp = YES;
                    311:   if (fixedaddress(ap)) q->fixed = YES;
                    312:   q->vtype = ap->vtype;
                    313:   q->varlist = NULL;
                    314:   if (vstg == STGCOMMON)
                    315:     {
                    316:       q->commonlink = commonvars;
                    317:       commonvars = q;
                    318:     }
                    319:   return q;
                    320: }
                    321: 
                    322: 
                    323: 
                    324: LOCAL VARNODE *getvar(ainfo, ap)
                    325: ADDRNODE *ainfo;
                    326: Addrp ap;
                    327: 
                    328: {
                    329:   register VARNODE *q;
                    330:   register VARNODE *q1;
                    331: 
                    332:   int memoffset;
                    333: 
                    334:   if (!ISVAR(ap))
                    335:     fatal("regalloc:  bad data sent to getvar");
                    336: 
                    337:   memoffset = ap->memoffset->constblock.const.ci;
                    338: 
                    339:   for (q = ainfo->varlist; q; q = q->link)
                    340:     if (q->memoffset == memoffset)
                    341:       return q;
                    342: 
                    343:   q1 = ainfo->varlist;
                    344:   ainfo->varlist = q = ALLOC(varnode);
                    345:   q->link = q1;
                    346:   q->memoffset = memoffset;
                    347:   q->stgp = (Addrp) cpexpr(ap);
                    348:   return q;
                    349: }
                    350: 
                    351: 
                    352: LOCAL ADDRNODE *lookupaddr(vstg, memno)
                    353: field vstg;
                    354: int memno;
                    355: 
                    356: {
                    357:   int key;
                    358:   register ADDRNODE *q;
                    359: 
                    360:   key = (256*vstg + memno) % VARTABSIZE;
                    361: 
                    362:   for (q = vartable[key]; q; q = q->link)
                    363:     if ((q->vstg == vstg) && (q->memno == memno))
                    364:       return q;
                    365: 
                    366:   fatal("regalloc:  lookupaddr");
                    367: }
                    368: 
                    369: 
                    370: LOCAL VARNODE *lookupvar(ainfo, memoffset)
                    371: ADDRNODE *ainfo;
                    372: int memoffset;
                    373: 
                    374: {
                    375:   register VARNODE *q;
                    376: 
                    377:   for (q = ainfo->varlist; q; q = q->link)
                    378:     if (q->memoffset == memoffset)
                    379:       return q;
                    380: 
                    381:   fatal("regalloc:  lookupvar");
                    382: }
                    383: 
                    384: 
                    385: 
                    386: LOCAL int invartable(p)
                    387: REGNODE *p;
                    388: 
                    389: {
                    390:   field vstg;
                    391:   int memno;
                    392:   int key;
                    393:   register ADDRNODE *q;
                    394: 
                    395:   vstg = p->vstg;
                    396:   memno = p->memno;
                    397:   key = (256*vstg + memno) % VARTABSIZE;
                    398: 
                    399:   for (q = vartable[key]; q; q = q->link)
                    400:     if ((q->vstg == vstg) && (q->memno == memno))
                    401:       return YES;
                    402: 
                    403:   return NO;
                    404: }
                    405: 
                    406: 
                    407: 
                    408: LOCAL freevartab()
                    409: 
                    410: {
                    411:   register ADDRNODE *p;
                    412:   ADDRNODE *p1;
                    413:   register VARNODE *q;
                    414:   VARNODE *q1;
                    415:   register int i;
                    416: 
                    417:   for (i = 0; i < VARTABSIZE; i++)
                    418:     if (vartable[i])
                    419:       {
                    420:        p = vartable[i];
                    421:        vartable[i] = NULL;
                    422: 
                    423:        while (p)
                    424:          {
                    425:            for (q = p->varlist; q; q = q1)
                    426:              {
                    427:                q1 = q->link;
                    428:                frexpr(q->stgp);
                    429:                free ((char *) q);
                    430:              }
                    431:            p1 = p->link;
                    432:            free((char *) p);
                    433:            p = p1;
                    434:          }
                    435:       }
                    436: }
                    437: 
                    438: 
                    439: 
                    440: LOCAL insertset(vstg, memno, memoffset)
                    441: field vstg;
                    442: int memno;
                    443: int memoffset;
                    444: 
                    445: {
                    446:   register SETNODE *p;
                    447:   SETNODE *q;
                    448: 
                    449:   if (allset) return;
                    450:   for (p = setlist; p; p = p->link)
                    451:     if((p->vstg == vstg) && (p->memno == memno) && (p->memoffset == memoffset))
                    452:       return;
                    453: 
                    454:   q = p;
                    455:   setlist = p = ALLOC(setnode);
                    456:   p->link = q;
                    457:   p->vstg = vstg;
                    458:   p->memno = memno;
                    459:   p->memoffset = memoffset;
                    460:   return;
                    461: }
                    462: 
                    463: 
                    464: 
                    465: LOCAL int insetlist(vstg, memno, memoffset)
                    466: field vstg;
                    467: int memno;
                    468: int memoffset;
                    469: 
                    470: {
                    471:   register SETNODE *p;
                    472: 
                    473:   if (allset) return YES;
                    474:   for (p = setlist; p; p = p->link)
                    475:     if((p->vstg == vstg) && (p->memno == memno) && (p->memoffset == memoffset))
                    476:       return YES;
                    477: 
                    478:   return NO;
                    479: }
                    480: 
                    481: 
                    482: 
                    483: LOCAL clearsets()
                    484: 
                    485: {
                    486:   register SETNODE *p, *q;
                    487: 
                    488:   allset = NO;
                    489: 
                    490:   p = setlist;
                    491:   while (p)
                    492:     {
                    493:       q = p->link;
                    494:       free ((char *) p);
                    495:       p = q;
                    496:     }
                    497:   setlist = NULL;
                    498:   return;
                    499: }
                    500: 
                    501: 
                    502: 
                    503: LOCAL alreg()
                    504: 
                    505: {
                    506:   register Slotp sp;
                    507:   register int i;
                    508:   register ADDRNODE *p;
                    509:   register VARNODE *q;
                    510:   Slotp sp1, sp2;
                    511:   ADDRNODE *addrinfo;
                    512:   VARNODE *varinfo;
                    513:   struct Labelblock **lp;
                    514:   int toptrack;
                    515:   int track[MAXREGVAR];
                    516:   Addrp ap, ap1;
                    517:   DOQUEUE *dqp;
                    518:   REGDATA *rp;
                    519:   REGNODE *regp;
                    520: 
                    521:   if (nregvar >= maxregvar) return;
                    522: 
                    523:   commonvars = NULL;
                    524:   docount = 0;
                    525: 
                    526:   for (sp = dohead; sp != doend->next; sp = sp->next)
                    527:     switch (sp->type)
                    528:       {
                    529:       case SKLABEL:
                    530:        insertlabel(sp->label);
                    531:        break;
                    532: 
                    533:       case SKARIF:
                    534:       case SKASGOTO:
                    535:       case SKCALL:
                    536:       case SKCMGOTO:
                    537:       case SKEQ:
                    538:       case SKIFN:
                    539:       case SKIOIFN:
                    540:       case SKSTOP:
                    541:       case SKPAUSE:
                    542:       case SKRETURN:
                    543:        scanvars(sp->expr);
                    544:        break;
                    545: 
                    546:       case SKDOHEAD:
                    547:        ++docount;
                    548:        break;
                    549: 
                    550:       case SKENDDO:
                    551:        --docount;
                    552:        break;
                    553:      
                    554:       case SKNULL:
                    555:       case SKGOTO:
                    556:       case SKASSIGN:
                    557:        break;
                    558: 
                    559:       default:
                    560:        badthing ("SKtype", "alreg-1", sp->type);
                    561:       }
                    562: 
                    563:   loopcost = 0;
                    564:   docount = 1;
                    565:   commonunusable = NO;
                    566:   if (! dohead->nullslot) fatal ("missing dohead->nullslot -cbb");
                    567:   for (sp = dohead->next, globalbranch = NO;
                    568:        docount;
                    569:        sp = sp->next, clearsets(), globalbranch = NO)
                    570:     if (docount > 1)
                    571:       switch (sp->type)
                    572:        {
                    573:        case SKDOHEAD:
                    574:          docount++;
                    575:          break;
                    576: 
                    577:        case SKENDDO:
                    578:          docount--;
                    579: 
                    580:        default:
                    581:          break;
                    582:        }
                    583:     else
                    584:       switch (sp->type)
                    585:        {
                    586:        case SKARIF:
                    587: #define LM   ((struct Labelblock * *)sp->ctlinfo)[0]->labelno 
                    588: #define LZ   ((struct Labelblock * *)sp->ctlinfo)[1]->labelno 
                    589: #define LP   ((struct Labelblock * *)sp->ctlinfo)[2]->labelno 
                    590: 
                    591:          if (!locallabel(LM) || !locallabel(LZ) || !locallabel(LP))
                    592:            {
                    593:              setall();
                    594:              globalbranch = YES;
                    595:            }
                    596:          countrefs(sp->expr);
                    597:          break;
                    598: 
                    599:        case SKASGOTO:
                    600:          setall();
                    601:          globalbranch = YES;
                    602:          countrefs(sp->expr);
                    603:          break;
                    604: 
                    605:        case SKCMGOTO:
                    606:          lp = (struct Labelblock **) sp->ctlinfo;
                    607:          for (i = 0; i < sp->label; i++, lp++)
                    608:            if (!locallabel((*lp)->labelno))
                    609:              {
                    610:                setall();
                    611:                globalbranch = YES;
                    612:                break;
                    613:              }
                    614:          countrefs(sp->expr);
                    615:          break;
                    616: 
                    617:        case SKDOHEAD:
                    618:          globalbranch = YES;
                    619:          loopcost = 2;
                    620:          docount++;
                    621:          break;
                    622: 
                    623:        case SKENDDO:
                    624:          docount = 0;
                    625:          break;
                    626: 
                    627:        case SKGOTO:
                    628:          if (!locallabel(sp->label))
                    629:            {
                    630:              setall();
                    631:              globalbranch = YES;
                    632:            }
                    633:          break;
                    634: 
                    635:        case SKIFN:
                    636:        case SKIOIFN:
                    637:          if (!locallabel(sp->label))
                    638:            {
                    639:              setall();
                    640:              globalbranch = YES;
                    641:            }
                    642:          countrefs(sp->expr);
                    643:          break;
                    644: 
                    645:        case SKEQ:
                    646:        case SKCALL:
                    647:        case SKSTOP:
                    648:        case SKPAUSE:
                    649:          linearcode = YES;
                    650:          countrefs(sp->expr);
                    651:          linearcode = NO;
                    652:          break;
                    653:        }
                    654: 
                    655:   topregvar = toplcv = nregvar - 1;
                    656: 
                    657:   for (i = 0; i < nregvar; i++)
                    658:     {
                    659:       ap = memversion(regnamep[i]);
                    660:       regtab[i] = rp = ALLOC(regdata);
                    661:       rp->vstg = ap->vstg;
                    662:       rp->vtype = ap->vtype;
                    663:       rp->memno = ap->memno;
                    664:       rp->memoffset = ap->memoffset->constblock.const.ci;
                    665:       rp->isarrayarg = NO;
                    666:       rp->stgp = ap;
                    667:     }
                    668: 
                    669:   for (i = 0; i < MAXREGVAR; i++)
                    670:     track[i] = YES;
                    671: 
                    672:   for (dqp = dqptr->down; dqp; dqp = dqp->down)
                    673:     {
                    674:       if (dqp->nregvars - 1 > topregvar)
                    675:        topregvar = dqp->nregvars -1;
                    676:       for (i = toplcv + 1; i < dqp->nregvars; i++)
                    677:        if (track[i])
                    678:          if (regp = dqp->reg[i])
                    679:            if (rp = regtab[i])
                    680:              {
                    681:                if (!samevar(rp, regp))
                    682:                  track[i] = NO;
                    683:              }
                    684:            else if (invartable(regp))
                    685:              {
                    686:                regtab[i] = rp = ALLOC(regdata);
                    687:                rp->vstg = regp->vstg;
                    688:                rp->vtype = regp->vtype;
                    689:                rp->memno = regp->memno;
                    690:                rp->memoffset = regp->memoffset;
                    691:                addrinfo = lookupaddr(rp->vstg, rp->memno);
                    692:                if (regp->isarrayarg)
                    693:                  {
                    694:                    rp->isarrayarg = YES;
                    695:                    rp->refs = addrinfo->refs;
                    696:                  }
                    697:                else
                    698:                  {
                    699:                    varinfo = lookupvar(addrinfo, regp->memoffset);
                    700:                    rp->refs = varinfo->refs;
                    701:                    rp->stgp = (Addrp) cpexpr(varinfo->stgp);
                    702:                    rp->istemp = addrinfo->istemp;
                    703:                    rp->isset = varinfo->isset;
                    704:                    rp->setfirst = varinfo->setfirst;
                    705:                  }
                    706:              }
                    707:            else
                    708:               track[i] = NO;
                    709:          else
                    710:            track[i] = NO;
                    711:     }
                    712: 
                    713:   toptrack = topregvar;
                    714: 
                    715:   for (i = toplcv + 1; i <= topregvar; i++)
                    716:     if (regtab[i])
                    717:       if ((track[i] == NO) || (regtab[i]->refs <= 0))
                    718:         {
                    719:          free((char *) regtab[i]);
                    720:          regtab[i] = NULL;
                    721:         }
                    722: 
                    723:   tabletop = -1;
                    724:   if (topregvar < maxregvar - 1)
                    725:     for (i = 0; i < VARTABSIZE; i++)
                    726:       for (p = vartable[i]; p; p = p->link)
                    727:        {
                    728:          entableaddr(p);
                    729:          if ((!p->loopset) &&
                    730:              (!p->mixedtype) &&
                    731:              (p->vstg != STGARG) &&
                    732:              !((p->vstg == STGCOMMON) && ((!p->fixed) || commonunusable)))
                    733:            for (q = p->varlist; q; q = q->link)
                    734:              entablevar(q);
                    735:        }
                    736: 
                    737:   for (i = 0; (i <= tabletop) && (topregvar + 1 < maxregvar); i++)
                    738:     {
                    739:       if (inregtab(rt[i]) || (loopcost && rt[i]->isset))
                    740:        continue;
                    741:       topregvar++;
                    742:       regtab[topregvar] = rp = ALLOC(regdata);
                    743:       rp->vstg = rt[i]->vstg;
                    744:       rp->vtype = rt[i]->vtype;
                    745:       rp->memno = rt[i]->memno;
                    746:       rp->memoffset = rt[i]->memoffset;
                    747:       rp->refs = rt[i]->refs;
                    748:       rp->stgp = (Addrp) cpexpr(rt[i]->stgp);
                    749:       rp->isarrayarg = rt[i]->isarrayarg;
                    750:       rp->istemp = rt[i]->istemp;
                    751:       rp->isset = rt[i]->isset;
                    752:       rp->setfirst = rt[i]->setfirst;
                    753:     }
                    754: 
                    755:   for (i = toplcv + 1; i <= topregvar; i++)
                    756:     {
                    757:       if (rp = regtab[i])
                    758:        if (rp->isarrayarg)
                    759:          {
                    760:            ap = ALLOC(Addrblock);
                    761:            ap->tag = TADDR;
                    762:            ap->vstg = STGREG;
                    763:            ap->vtype = TYADDR;
                    764:            ap->vclass = CLVAR;
                    765:            ap->memno = regnum[i];
                    766:            ap->memoffset = ICON(0);
                    767: 
                    768:            ap1 = ALLOC(Addrblock);
                    769:            ap1->tag = TADDR;
                    770:            ap1->vstg = rp->vstg;
                    771:            ap1->vtype = rp->vtype;
                    772:            ap1->vclass = CLVAR;
                    773:            ap1->memno = rp->memno;
                    774:            ap1->memoffset = ICON(0);
                    775: 
                    776:            insertassign(dohead, ap, addrof(ap1));
                    777:          }
                    778:         else if (!(rp->setfirst && rp->istemp))
                    779:          {
                    780:            if (rp->istemp)
                    781:              for (sp = newcode; sp && sp != dohead; sp = sp->next)
                    782:                if (sp->type == SKEQ)
                    783:                  {
                    784:                    ap = (Addrp) sp->expr->exprblock.leftp;
                    785:                    if ((ap->vstg == rp->vstg) && (ap->memno == rp->memno) &&
                    786:                        fixedaddress(ap) &&
                    787:                        (ap->memoffset->constblock.const.ci == rp->memoffset))
                    788:                      {
                    789:                        changetoreg(ap, i);
                    790:                        goto L1;
                    791:                      }
                    792:                  }
                    793:            ap = (Addrp) cpexpr(rp->stgp);
                    794:            changetoreg(ap, i);
                    795:            insertassign(dohead, ap, cpexpr(rp->stgp));
                    796:          }
                    797: L1:;
                    798:     }
                    799: 
                    800:   for (i = toplcv + 1; i <= topregvar; i++)
                    801:     if (rp = regtab[i])
                    802:       if (rp->isset && !(rp->istemp || rp->isarrayarg))
                    803:        {
                    804:          ap = (Addrp) cpexpr(rp->stgp);
                    805:          changetoreg(ap, i);
                    806:          appendassign(doend, cpexpr(rp->stgp), ap);
                    807:        }
                    808: 
                    809:   docount = 1;
                    810:   clearmems();
                    811:   setregs();
                    812:   sp = dohead->next;
                    813:   if (loopcost)
                    814:     for (i = toptrack + 1; i <= topregvar; i++)
                    815:       if ((rp = regtab[i]) && !rp->isarrayarg)
                    816:        {
                    817:          ap = (Addrp) cpexpr(rp->stgp);
                    818:          changetoreg(ap, i);
                    819:          insertassign(sp, cpexpr(rp->stgp), ap);
                    820:        }
                    821: 
                    822:   for ( sp = dohead->next;
                    823:        docount || sp->type != SKNULL;
                    824:        sp = sp->next)
                    825:     if (docount > 1)
                    826:       switch (sp->type)
                    827:        {
                    828:        case SKDOHEAD:
                    829:          docount++;
                    830:          break;
                    831: 
                    832:        case SKENDDO:
                    833:          if (--docount == 1)
                    834:            {
                    835:              /*
                    836:               * Remove redundant stores to memory.
                    837:               */
                    838:              sp1 = sp->nullslot->next;
                    839:              while (sp1)
                    840:                {
                    841:                  if (regtomem(sp1))
                    842:                    {
                    843:                      ap = (Addrp) sp1->expr->exprblock.rightp;
                    844:                      sp2 = sp1->next;
                    845:                      for (i = toplcv + 2; i <= toptrack; i++)
                    846:                        if (regtab[i] && (regnum[i] == ap->memno))
                    847:                          {
                    848:                            deleteslot(sp1);
                    849:                            break;
                    850:                          }
                    851:                      sp1 = sp2;
                    852:                    }
                    853:                  else
                    854:                    sp1 = NULL;
                    855:                }
                    856: 
                    857:              /*
                    858:               * Restore register variables (complement to DOHEAD code).
                    859:               */
                    860:              sp1 = sp->nullslot->next;
                    861:              for (i = toplcv + 1; i <= topregvar; i++)
                    862:                if (rp = regtab[i])
                    863:                  if (!regdefined[i])
                    864:                    if (i >= dqp->nregvars || !samevar(rp, dqp->reg[i]))
                    865:                      {
                    866:                        ap = (Addrp) cpexpr(rp->stgp);
                    867:                        changetoreg(ap, i);
                    868:                        insertassign(sp1, ap, cpexpr(rp->stgp));
                    869:                        regdefined[i] = YES;
                    870:                      }
                    871: 
                    872:              clearmems();
                    873:              if (toplcv + 1 < maxregvar)
                    874:                memdefined[toplcv + 1] = YES;
                    875:              sp = sp1->prev;
                    876:            }
                    877:          break;
                    878:        }
                    879:       else
                    880:        {
                    881:          setregs();
                    882:          for (i = 0; i <= MAXREGVAR; i++)
                    883:            regaltered[i] = NO;
                    884:          globalbranch = NO;
                    885: 
                    886:          switch (sp->type)
                    887:            {
                    888:            case SKLABEL:
                    889:              clearmems();
                    890:              break;
                    891: 
                    892:            case SKGOTO:
                    893:              if (!locallabel(sp->label))
                    894:                gensetall(sp);
                    895:              break;
                    896: 
                    897:            case SKENDDO:
                    898:              docount = 0;
                    899:              break;
                    900: 
                    901:            case SKRETURN:
                    902:              gensetreturn(sp);
                    903:              linearcode = YES;
                    904:              regwrite(sp, sp->expr);
                    905:              linearcode = NO;
                    906:              break;
                    907: 
                    908:            case SKDOHEAD:
                    909:              /*
                    910:               * If one of the current loop's register variables is not in
                    911:               * register in an inner loop, we must save it.  It's a pity
                    912:               * we don't save enough info to optimize this properly...
                    913:               */
                    914:              for (dqp = dqptr->down; dqp; dqp = dqp->down)
                    915:                if (dqp->dohead == sp)
                    916:                  break;
                    917:              if (dqp == NULL)
                    918:                fatal("confused in alreg loop analysis");
                    919:              for (i = toplcv + 1; i <= topregvar; i++)
                    920:                if (rp = regtab[i])
                    921:                  if (!memdefined[i])
                    922:                    if (i >= dqp->nregvars || !samevar(rp, dqp->reg[i]))
                    923:                      {
                    924:                        ap = (Addrp) cpexpr(rp->stgp);
                    925:                        changetoreg(ap, i);
                    926:                        insertassign(sp, cpexpr(rp->stgp), ap);
                    927:                        memdefined[i] = YES;
                    928:                        regdefined[i] = NO;
                    929:                      }
                    930: 
                    931:              docount++;
                    932:              globalbranch = YES;
                    933:              break;
                    934: 
                    935:            case SKEQ:
                    936:            case SKCALL:
                    937:            case SKSTOP:
                    938:            case SKPAUSE:
                    939:              linearcode = YES;
                    940:              regwrite(sp, sp->expr);
                    941:              for (i = toplcv + 1; i <= topregvar; i++)
                    942:                if (!regdefined[i] && ((rp = regtab[i]) && rp->isset))
                    943:                  {
                    944:                    ap = (Addrp) cpexpr(rp->stgp);
                    945:                    changetoreg(ap, i);
                    946:                    appendassign(sp, ap, cpexpr(rp->stgp));
                    947:                    sp = sp->next;
                    948:                    regdefined[i] = YES;
                    949:                  }
                    950:              linearcode = NO;
                    951: 
                    952:              /*
                    953:               * Eliminate redundant register moves.
                    954:               */
                    955:              if (regtoreg(sp))
                    956:                {
                    957:                  ap = (Addrp) sp->expr->exprblock.leftp;
                    958:                  sp1 = sp->prev;
                    959:                  for (i = toplcv + 1; i <= toptrack; i++)
                    960:                    if (regtab[i] && (regnum[i] == ap->memno))
                    961:                      {
                    962:                        deleteslot(sp);
                    963:                        sp = sp1;
                    964:                        break;
                    965:                      }
                    966:                }
                    967:              break;
                    968: 
                    969:            case SKARIF:
                    970:              if (!locallabel(LM) || !locallabel(LZ) || !locallabel(LP))
                    971:                {
                    972:                  gensetall(sp);
                    973:                  globalbranch = YES;
                    974:                }
                    975:              regwrite(sp, sp->expr);
                    976:              break;
                    977: 
                    978:            case SKASGOTO:
                    979:              gensetall(sp);
                    980:              globalbranch = YES;
                    981:              regwrite(sp, sp->expr);
                    982:              break;
                    983: 
                    984:            case SKCMGOTO:
                    985:              lp = (struct Labelblock **) sp->ctlinfo;
                    986:              for (i = 0; i < sp->label; i++, lp++)
                    987:                if (!locallabel((*lp)->labelno))
                    988:                  {
                    989:                    gensetall(sp);
                    990:                    globalbranch = YES;
                    991:                    break;
                    992:                  }
                    993:              regwrite(sp, sp->expr);
                    994:              break;
                    995: 
                    996:            case SKIFN:
                    997:            case SKIOIFN:
                    998:              if (!locallabel(sp->label))
                    999:                {
                   1000:                  gensetall(sp);
                   1001:                  globalbranch = YES;
                   1002:                }
                   1003:              regwrite(sp, sp->expr);
                   1004:              break;
                   1005: 
                   1006:            case SKNULL:
                   1007:            case SKASSIGN:
                   1008:              break;
                   1009: 
                   1010:            default:
                   1011:              badthing ("SKtype","alreg-3",sp->type);
                   1012:            }
                   1013:          
                   1014:          for (i = toplcv + 1; i <= topregvar; i++)
                   1015:            if (regaltered[i])
                   1016:              memdefined[i] = NO;
                   1017:        }
                   1018: 
                   1019:   if (topregvar + 1 > highregvar)
                   1020:     highregvar = topregvar + 1;
                   1021:   dqptr->nregvars = topregvar + 1;
                   1022:   for (i = 0; i <= topregvar; i++)
                   1023:     if (rp = regtab[i])
                   1024:       {
                   1025:        dqptr->reg[i] = regp = ALLOC(regnode);
                   1026:        regp->vstg = rp->vstg;
                   1027:        regp->vtype = rp->vtype;
                   1028:        regp->memno = rp->memno;
                   1029:        regp->memoffset = rp->memoffset;
                   1030:        regp->isarrayarg = rp->isarrayarg;
                   1031:        frexpr(rp->stgp);
                   1032:        free((char *) rp);
                   1033:        regtab[i] = NULL;
                   1034:       }
                   1035: 
                   1036:   while (tabletop >= 0)
                   1037:     free((char *) rt[tabletop--]);
                   1038:   freelabtab();
                   1039:   freevartab();
                   1040:   return;
                   1041: }
                   1042: 
                   1043: 
                   1044: 
                   1045: LOCAL scanvars(p)
                   1046: expptr p;
                   1047: 
                   1048: {
                   1049:   Addrp ap;
                   1050:   ADDRNODE *addrinfo;
                   1051:   VARNODE *varinfo;
                   1052:   chainp args;
                   1053:   VARNODE *q;
                   1054: 
                   1055:   if (p == NULL) return;
                   1056: 
                   1057:   switch (p->tag)
                   1058:     {
                   1059:     case TCONST:
                   1060:       return;
                   1061: 
                   1062:     case TEXPR:
                   1063:       switch (p->exprblock.opcode)
                   1064:        {
                   1065:        case OPASSIGN:
                   1066:          scanassign(p);
                   1067:          return;
                   1068: 
                   1069:        case OPPLUSEQ:
                   1070:        case OPSTAREQ:
                   1071:          scanopeq(p);
                   1072:          return;
                   1073: 
                   1074:        case OPCALL:
                   1075:          scancall(p);
                   1076:          return;
                   1077: 
                   1078:        default:
                   1079:          scanvars(p->exprblock.vleng);
                   1080:          scanvars(p->exprblock.leftp);
                   1081:          scanvars(p->exprblock.rightp);
                   1082:          return;
                   1083:        }
                   1084: 
                   1085:     case TADDR:
                   1086:       ap = (Addrp) p;
                   1087:       scanvars(ap->vleng);
                   1088:       scanvars(ap->memoffset);
                   1089:       if (!ISVAR(ap)) return;
                   1090: 
                   1091:       addrinfo = getaddr(ap);
                   1092:       if (fixedaddress(ap))
                   1093:        {
                   1094:          if (ISREGTYPE(ap->vtype))
                   1095:            {
                   1096:              varinfo = getvar(addrinfo, ap);
                   1097:              varinfo->isused = YES;
                   1098:            }
                   1099:        }
                   1100:       else
                   1101:        {
                   1102:          addrinfo->freeuse = YES;
                   1103:          for (q = addrinfo->varlist; q; q = q->link)
                   1104:            q->isused = YES;
                   1105:        }
                   1106:       return;
                   1107: 
                   1108:     case TLIST:
                   1109:       for (args = p->listblock.listp; args; args = args->nextp)
                   1110:        scanvars(args->datap);
                   1111:       return;
                   1112: 
                   1113:     default:
                   1114:       badtag ("regalloc:scanvars", p->tag);
                   1115:     }
                   1116: }
                   1117: 
                   1118: 
                   1119: 
                   1120: LOCAL scanassign(ep)
                   1121: Exprp ep;
                   1122: 
                   1123: {
                   1124:   Addrp lhs;
                   1125:   VARNODE *varinfo;
                   1126:   ADDRNODE *addrinfo;
                   1127: 
                   1128:   scanvars(ep->rightp);
                   1129:   if (ep->leftp->tag == TADDR)
                   1130:     {
                   1131:       lhs = (Addrp) ep->leftp;
                   1132:       scanvars(lhs->vleng);
                   1133:       scanvars(lhs->memoffset);
                   1134:       if ((lhs->vstg == STGREG) || (lhs->vstg == STGPREG))
                   1135:        return;
                   1136:       if (ISVAR(lhs))
                   1137:        {
                   1138:           addrinfo = getaddr(lhs);
                   1139:           addrinfo->isset = YES;
                   1140:          if (docount > 1)
                   1141:                addrinfo->loopset = YES;
                   1142:           if (fixedaddress(lhs) && ISREGTYPE(lhs->vtype))
                   1143:            {
                   1144:              varinfo = getvar(addrinfo, lhs);
                   1145:              if (addrinfo->freeuse) varinfo->isused = YES;
                   1146:              varinfo->isset = YES;
                   1147:              if (!addrinfo->freeuse && !varinfo->isused)
                   1148:                varinfo->setfirst = YES;
                   1149:            }
                   1150:         }
                   1151:     }
                   1152:   else
                   1153:     badtag ("regalloc:scanassign", ep->leftp->tag);
                   1154: }
                   1155: 
                   1156: 
                   1157: 
                   1158: LOCAL scanopeq(ep)
                   1159: Exprp ep;
                   1160: 
                   1161: {
                   1162:   Addrp lhs;
                   1163:   ADDRNODE *addrinfo;
                   1164:   VARNODE *varinfo;
                   1165: 
                   1166:   scanvars(ep->rightp);
                   1167:   if (ep->leftp->tag == TADDR)
                   1168:     {
                   1169:       lhs = (Addrp) ep->leftp;
                   1170:       scanvars(lhs->vleng);
                   1171:       scanvars(lhs->memoffset);
                   1172:       if ((lhs->vstg == STGREG) || (lhs->vstg == STGPREG))
                   1173:        return;
                   1174:       if (ISVAR(lhs))
                   1175:        {
                   1176:           addrinfo = getaddr(lhs);
                   1177:           addrinfo->isset = YES;
                   1178:          if (docount > 1)
                   1179:                addrinfo->loopset = YES;
                   1180:           if (fixedaddress(lhs))
                   1181:            {
                   1182:              if (ISREGTYPE(lhs->vtype))
                   1183:                {
                   1184:                  varinfo = getvar(addrinfo, lhs);
                   1185:                  varinfo->isused = YES;
                   1186:                  varinfo->isset = YES;
                   1187:                }
                   1188:            }
                   1189:         }
                   1190:       else
                   1191:        addrinfo->freeuse = YES;
                   1192:     }
                   1193:   else
                   1194:     badtag ("regalloc:scanopeq", ep->leftp->tag);
                   1195: }
                   1196: 
                   1197: 
                   1198: 
                   1199: LOCAL scancall(ep)
                   1200: Exprp ep;
                   1201: 
                   1202: {
                   1203:   Addrp lhs;
                   1204:   chainp args;
                   1205:   Addrp ap;
                   1206:   VARNODE *varinfo;
                   1207:   ADDRNODE *addrinfo;
                   1208: 
                   1209:   lhs = (Addrp) ep->leftp;
                   1210:   scanvars(lhs->vleng);
                   1211:   scanvars(lhs->memoffset);
                   1212: 
                   1213:   if (ep->rightp == NULL) return;
                   1214: 
                   1215:   if (lhs->vstg != STGINTR)
                   1216:     {
                   1217:       args = ep->rightp->listblock.listp;
                   1218:       for (; args; args = args->nextp)
                   1219:        {
                   1220:          if (args->datap->tag == TADDR)
                   1221:            {
                   1222:              ap = (Addrp) args->datap;
                   1223:              scanvars(ap->vleng);
                   1224:              scanvars(ap->memoffset);
                   1225:              if (!ISVAR(ap)) continue;
                   1226: 
                   1227:              addrinfo = getaddr(ap);
                   1228:              addrinfo->isset = YES;
                   1229:              if (docount > 1)
                   1230:                addrinfo->loopset = YES;
                   1231:              if (fixedaddress(ap))
                   1232:                {
                   1233:                  varinfo = getvar(addrinfo, ap);
                   1234:                  if (ap->vstg != STGCONST)
                   1235:                    varinfo->isset = YES;
                   1236:                  varinfo->isused = YES;
                   1237:                }
                   1238:              else
                   1239:                addrinfo->freeuse = YES;
                   1240:            }
                   1241:          else
                   1242:            scanvars(args->datap);
                   1243:        }
                   1244:     }
                   1245:   else
                   1246:     scanvars(ep->rightp);
                   1247: 
                   1248:   return;
                   1249: }
                   1250: 
                   1251: 
                   1252: 
                   1253: LOCAL int fixedaddress(ap)
                   1254: Addrp ap;
                   1255: 
                   1256: {
                   1257:   if (!ap->memoffset)
                   1258:     return NO;
                   1259:   return (ISCONST(ap->memoffset) && ISINT(ap->memoffset->headblock.vtype));
                   1260: }
                   1261: 
                   1262: 
                   1263: 
                   1264: LOCAL countrefs(p)
                   1265: expptr p;
                   1266: 
                   1267: {
                   1268:   Addrp ap;
                   1269:   ADDRNODE *addrinfo;
                   1270:   VARNODE *varinfo;
                   1271:   VARNODE *vp;
                   1272:   chainp args;
                   1273: 
                   1274:   if (p == NULL) return;
                   1275: 
                   1276:   switch (p->tag)
                   1277:     {
                   1278:     case TCONST:
                   1279:       return;
                   1280: 
                   1281:     case TEXPR:
                   1282:       switch (p->exprblock.opcode)
                   1283:        {
                   1284:        case OPCALL:
                   1285:          if (p->exprblock.leftp->tag != TADDR)
                   1286:            badtag ("regalloc:countrefs", p->exprblock.leftp->tag);
                   1287:          countrefs(p->exprblock.leftp->addrblock.vleng);
                   1288:          countrefs(p->exprblock.leftp->addrblock.memoffset);
                   1289: 
                   1290:          if (p->exprblock.leftp->addrblock.vstg != STGINTR)
                   1291:            {
                   1292:              if (!commonunusable)
                   1293:                if (linearcode)
                   1294:                  setcommon();
                   1295:                else
                   1296:                  commonunusable = YES;
                   1297:              if (p->exprblock.rightp == NULL) return;
                   1298:              args = p->exprblock.rightp->listblock.listp;
                   1299:              for (; args; args = args->nextp)
                   1300:                if (args->datap->tag == TADDR)
                   1301:                  {
                   1302:                    ap = (Addrp) args->datap;
                   1303:                    countrefs(ap->vleng);
                   1304:                    countrefs(ap->memoffset);
                   1305:                    if (!ISVAR(ap) || ap->vstg == STGCONST) continue;
                   1306:                    addrinfo = lookupaddr(ap->vstg, ap->memno);
                   1307:                    if (ap->vstg == STGARG)
                   1308:                      addrinfo->refs++;
                   1309:                    for (vp = addrinfo->varlist; vp; vp = vp->link)
                   1310:                      if (linearcode)
                   1311:                        if (!insetlist(ap->vstg, ap->memno, vp->memoffset))
                   1312:                          if (addrinfo->istemp)
                   1313:                            vp->refs--;
                   1314:                          else
                   1315:                            {
                   1316:                              vp->refs -= 2;
                   1317:                              insertset(ap->vstg, ap->memno, vp->memoffset);
                   1318:                            }
                   1319:                        else
                   1320:                          vp->refs--;
                   1321:                      else
                   1322:                        {
                   1323:                          if (!addrinfo->istemp)
                   1324:                            vp->unusable = YES;
                   1325:                        }
                   1326:                  }
                   1327:                else
                   1328:                  countrefs(args->datap);
                   1329:             }
                   1330:          else
                   1331:            {
                   1332:              if (p->exprblock.rightp == NULL) return;
                   1333:              args = p->exprblock.rightp->listblock.listp;
                   1334:              for (; args; args = args->nextp)
                   1335:                if (args->datap->tag == TADDR)
                   1336:                  {
                   1337:                    ap = (Addrp) args->datap;
                   1338:                    countrefs(ap->vleng);
                   1339:                    countrefs(ap->memoffset);
                   1340:                    if (!ISVAR(ap) || ap->vstg == STGCONST) continue;
                   1341:                    addrinfo = lookupaddr(ap->vstg, ap->memno);
                   1342:                    addrinfo->refs++;
                   1343:                    for (vp = addrinfo->varlist; vp; vp = vp->link)
                   1344:                      if (!insetlist(ap->vstg, ap->memno, vp->memoffset))
                   1345:                        {
                   1346:                          vp->refs--;
                   1347:                          insertset(ap->vstg, ap->memno, vp->memoffset);
                   1348:                        }
                   1349:                  }
                   1350:                else
                   1351:                  countrefs(args->datap);
                   1352:            }
                   1353:          return;
                   1354: 
                   1355:        case OPASSIGN:
                   1356:        case OPPLUSEQ:
                   1357:        case OPSTAREQ:
                   1358:          countrefs(p->exprblock.vleng);
                   1359:          countrefs(p->exprblock.rightp);
                   1360:          ap = (Addrp) p->exprblock.leftp;
                   1361:          if (fixedaddress(ap))
                   1362:            if (globalbranch)
                   1363:              {
                   1364:                countrefs(ap->vleng);
                   1365:                countrefs(ap->memoffset);
                   1366:              }
                   1367:            else
                   1368:              countrefs(ap);
                   1369:          else if (linearcode)
                   1370:            {
                   1371:              countrefs(ap);
                   1372:              for (vp = lookupaddr(ap->vstg, ap->memno)->varlist;
                   1373:                   vp;
                   1374:                   vp = vp->link)
                   1375:                vp->refs--;
                   1376:            }
                   1377:          else
                   1378:            {
                   1379:              countrefs(ap);
                   1380:              for (vp = lookupaddr(ap->vstg, ap->memno)->varlist;
                   1381:                   vp;
                   1382:                   vp = vp->link)
                   1383:                vp->unusable = YES;
                   1384:            }
                   1385:          return;
                   1386: 
                   1387:        default:
                   1388:          countrefs(p->exprblock.vleng);
                   1389:          countrefs(p->exprblock.leftp);
                   1390:          countrefs(p->exprblock.rightp);
                   1391:          return;
                   1392:        }
                   1393: 
                   1394:     case TADDR:
                   1395:       ap = (Addrp) p;
                   1396:       countrefs(ap->vleng);
                   1397:       countrefs(ap->memoffset);
                   1398:       if (!ISVAR(ap)) return;
                   1399: 
                   1400:       addrinfo = lookupaddr(ap->vstg, ap->memno);
                   1401:       if (ap->vstg == STGARG)
                   1402:        addrinfo->refs++;
                   1403: 
                   1404:       if (fixedaddress(ap))
                   1405:        {
                   1406:          if (ISREGTYPE(ap->vtype))
                   1407:            {
                   1408:              varinfo = lookupvar(addrinfo, ap->memoffset->constblock.const.ci);
                   1409:              varinfo->refs++;
                   1410:            }
                   1411:        }
                   1412:       else
                   1413:        for (vp = addrinfo->varlist; vp; vp = vp->link)
                   1414:          if (!insetlist(ap->vstg, ap->memno, vp->memoffset))
                   1415:            {
                   1416:              vp->refs--;
                   1417:              insertset(ap->vstg, ap->memno, vp->memoffset);
                   1418:            }
                   1419:       return;
                   1420: 
                   1421:     case TLIST:
                   1422:       args = p->listblock.listp;
                   1423:       for (; args; args = args->nextp)
                   1424:        countrefs(args->datap);
                   1425:       return;
                   1426: 
                   1427:     default:
                   1428:       badtag ("regalloc:countrefs", p->tag);
                   1429:     }
                   1430: }
                   1431: 
                   1432: 
                   1433: 
                   1434: LOCAL regwrite(sp, p)
                   1435: Slotp sp;
                   1436: expptr p;
                   1437: 
                   1438: {
                   1439:   register int i;
                   1440:   REGDATA *rp;
                   1441:   chainp args;
                   1442:   Addrp ap, ap1;
                   1443:   int memoffset;
                   1444: 
                   1445:   if (p == NULL) return;
                   1446: 
                   1447:   switch (p->tag)
                   1448:     {
                   1449:     case TCONST:
                   1450:       return;
                   1451: 
                   1452:     case TEXPR:
                   1453:       switch (p->exprblock.opcode)
                   1454:        {
                   1455:        case OPCALL:
                   1456:          ap = (Addrp) p->exprblock.leftp;
                   1457:          regwrite(sp, ap->vleng);
                   1458:          regwrite(sp, ap->memoffset);
                   1459:          if (ap->vstg != STGINTR)
                   1460:            {
                   1461:              if (linearcode)
                   1462:                {
                   1463:                  gensetcommon(sp);
                   1464:                  for (i = toplcv + 1; i <= topregvar; i++)
                   1465:                    if ((rp = regtab[i]) && (rp->vstg == STGCOMMON))
                   1466:                      regdefined[i] = NO;
                   1467:                }
                   1468:              if (p->exprblock.rightp == NULL) return;
                   1469:              args = p->exprblock.rightp->listblock.listp;
                   1470:              for (; args; args = args->nextp)
                   1471:                if (args->datap->tag == TADDR)
                   1472:                  {
                   1473:                    ap = (Addrp) args->datap;
                   1474:                    regwrite(sp, ap->vleng);
                   1475:                    regwrite(sp, ap->memoffset);
                   1476:                    for (i = toplcv + 1; i <= topregvar; i++)
                   1477:                      if ((rp = regtab[i]) &&
                   1478:                          !rp->isarrayarg &&
                   1479:                          !rp->istemp &&
                   1480:                          (rp->vstg == ap->vstg) &&
                   1481:                          (rp->memno == ap->memno))
                   1482:                        {
                   1483:                          regdefined[i] = NO;
                   1484:                          if (!memdefined[i])
                   1485:                            {
                   1486:                              ap1 = (Addrp) cpexpr(rp->stgp);
                   1487:                              changetoreg(ap1, i);
                   1488:                              insertassign(sp, cpexpr(rp->stgp), ap1);
                   1489:                              memdefined[i] = YES;
                   1490:                            }
                   1491:                        }
                   1492:                      else if (rp->isarrayarg &&
                   1493:                               (ap->vstg == STGARG) &&
                   1494:                               (ap->memno == rp->memno))
                   1495:                        {
                   1496:                          ap->vstg = STGPREG;
                   1497:                          ap->memno = regnum[i];
                   1498:                        }
                   1499:                  }
                   1500:                else
                   1501:                  regwrite(sp, args->datap);
                   1502:            }
                   1503:          else
                   1504:            {
                   1505:              if (p->exprblock.rightp == NULL) return;
                   1506:              args = p->exprblock.rightp->listblock.listp;
                   1507:              for (; args; args = args->nextp)
                   1508:                if (args->datap->tag == TADDR)
                   1509:                  {
                   1510:                    ap = (Addrp) args->datap;
                   1511:                    regwrite(sp, ap->vleng);
                   1512:                    regwrite(sp, ap->memoffset);
                   1513:                    for (i = toplcv + 1; i <= topregvar; i++)
                   1514:                      if ((rp = regtab[i]) &&
                   1515:                          !rp->isarrayarg &&
                   1516:                          !rp->istemp &&
                   1517:                          (rp->vstg == ap->vstg) &&
                   1518:                          (rp->memno == ap->memno) &&
                   1519:                          !memdefined[i])
                   1520:                        {
                   1521:                          ap1 = (Addrp) cpexpr(rp->stgp);
                   1522:                          changetoreg(ap1, i);
                   1523:                          insertassign(sp, cpexpr(rp->stgp), ap1);
                   1524:                          memdefined[i] = YES;
                   1525:                        }
                   1526:                      else if (rp->isarrayarg &&
                   1527:                               (ap->vstg == STGARG) &&
                   1528:                               (rp->memno == ap->memno))
                   1529:                        {
                   1530:                          ap->vstg = STGPREG;
                   1531:                          ap->memno = regnum[i];
                   1532:                        }
                   1533:                  }
                   1534:                else
                   1535:                  {
                   1536:                    regwrite(sp, args->datap);
                   1537:                  }
                   1538:            }
                   1539:          return;
                   1540: 
                   1541:        case OPASSIGN:
                   1542:        case OPPLUSEQ:
                   1543:        case OPSTAREQ:
                   1544:          regwrite(sp, p->exprblock.vleng);
                   1545:          regwrite(sp, p->exprblock.rightp);
                   1546:          ap = (Addrp) p->exprblock.leftp;
                   1547:          regwrite(sp, ap->vleng);
                   1548:          regwrite(sp, ap->memoffset);
                   1549: 
                   1550:          if (ap->vstg == STGARG)
                   1551:            for (i = toplcv + 1; i<=topregvar; i++)
                   1552:              if ((rp = regtab[i]) &&
                   1553:                  rp->isarrayarg &&
                   1554:                  (rp->memno == ap->memno))
                   1555:                {
                   1556:                  ap->vstg = STGPREG;
                   1557:                  ap->memno = regnum[i];
                   1558:                  return;
                   1559:                }
                   1560: 
                   1561:          if (fixedaddress(ap))
                   1562:            {
                   1563:              memoffset = ap->memoffset->constblock.const.ci;
                   1564:              for (i = toplcv + 1; i <= topregvar; i++)
                   1565:                if ((rp = regtab[i]) &&
                   1566:                    !rp->isarrayarg &&
                   1567:                    (rp->vstg == ap->vstg) &&
                   1568:                    (rp->memno == ap->memno) &&
                   1569:                    (rp->memoffset == memoffset))
                   1570:                  {
                   1571:                    changetoreg(ap, i);
                   1572:                    if (globalbranch)
                   1573:                      {
                   1574:                        p->exprblock.rightp = (expptr) cpexpr(p);
                   1575:                        p->exprblock.leftp = (expptr) cpexpr(rp->stgp);
                   1576:                        p->exprblock.opcode = OPASSIGN;
                   1577:                        memdefined[i] = YES;
                   1578:                      }
                   1579:                    else
                   1580:                      {
                   1581:                        regaltered[i] = YES;
                   1582:                        regdefined[i] = YES;
                   1583:                      }
                   1584:                  }
                   1585:              return;
                   1586:            }
                   1587: 
                   1588:          if (linearcode)
                   1589:            for (i = toplcv + 1; i <= topregvar; i++)
                   1590:              if ((rp = regtab[i]) &&
                   1591:                  !rp->isarrayarg &&
                   1592:                  (rp->vstg == ap->vstg) &&
                   1593:                  (rp->memno == ap->memno))
                   1594:                regdefined[i] = NO;
                   1595:          return;
                   1596: 
                   1597:        default:
                   1598:          regwrite(sp, p->exprblock.vleng);
                   1599:          regwrite(sp, p->exprblock.leftp);
                   1600:          regwrite(sp, p->exprblock.rightp);
                   1601:          return;
                   1602:        }
                   1603: 
                   1604:     case TADDR:
                   1605:       ap = (Addrp) p;
                   1606:       regwrite(sp, ap->vleng);
                   1607:       regwrite(sp, ap->memoffset);
                   1608: 
                   1609:       if (ap->vstg == STGARG)
                   1610:        for (i = toplcv + 1; i <= topregvar; i++)
                   1611:          if ((rp = regtab[i]) &&
                   1612:              rp->isarrayarg &&
                   1613:              (rp->memno == ap->memno))
                   1614:            {
                   1615:              ap->vstg = STGPREG;
                   1616:              ap->memno = regnum[i];
                   1617:              return;
                   1618:            }
                   1619: 
                   1620:       if (fixedaddress(ap))
                   1621:        {
                   1622:           memoffset = ap->memoffset->constblock.const.ci;
                   1623:          for (i = toplcv + 1; i <= topregvar; i++)
                   1624:            if ((rp = regtab[i]) &&
                   1625:                !rp->isarrayarg &&
                   1626:                (rp->vstg == ap->vstg) &&
                   1627:                (rp->memno == ap->memno) &&
                   1628:                (rp->memoffset == memoffset))
                   1629:              {
                   1630:                changetoreg(ap, i);
                   1631:                return;
                   1632:              }
                   1633:        }
                   1634:       else
                   1635:        {
                   1636:          for (i = toplcv + 1; i <= topregvar; i++)
                   1637:            if ((rp = regtab[i]) &&
                   1638:                !rp->isarrayarg &&
                   1639:                (rp->vstg == ap->vstg) &&
                   1640:                (rp->memno == ap->memno) &&
                   1641:                !memdefined[i])
                   1642:              {
                   1643:                ap1 = (Addrp) cpexpr(rp->stgp);
                   1644:                changetoreg(ap1, i);
                   1645:                insertassign(sp, cpexpr(rp->stgp), ap1);
                   1646:                memdefined[i] = YES;
                   1647:              }
                   1648:        }
                   1649:       return;
                   1650: 
                   1651:     case TLIST:
                   1652:       for (args = p->listblock.listp; args; args = args->nextp)
                   1653:        regwrite(sp, args->datap);
                   1654:       return;
                   1655: 
                   1656:     default:
                   1657:       badtag ("regalloc:regwrite", p->tag);
                   1658:     }
                   1659: }
                   1660: 
                   1661: 
                   1662: 
                   1663: LOCAL setcommon()
                   1664: 
                   1665: {
                   1666:   ADDRNODE *ap;
                   1667:   VARNODE *vp;
                   1668: 
                   1669:   for (ap = commonvars; ap; ap = ap->commonlink)
                   1670:     for (vp = ap->varlist; vp; vp = vp->link)
                   1671:       if (!insetlist(ap->vstg, ap->memno, vp->memoffset))
                   1672:        {
                   1673:          vp->refs -= 2;
                   1674:          insertset(ap->vstg, ap->memno, vp->memoffset);
                   1675:        }
                   1676:       else
                   1677:        vp->refs--;
                   1678: 
                   1679:   return;
                   1680: }
                   1681: 
                   1682:  
                   1683: 
                   1684: LOCAL setall()
                   1685: 
                   1686: {
                   1687:   register int i;
                   1688:   register ADDRNODE *p;
                   1689:   register VARNODE *q;
                   1690: 
                   1691:   for (i = 0; i < VARTABSIZE; i++)
                   1692:     for (p = vartable[i]; p; p = p->link)
                   1693:       if (p->istemp || !p->isset)
                   1694:        break;
                   1695:       else
                   1696:        for (q = p->varlist; q; q = q->link)
                   1697:          if (q->isset && !insetlist(p->vstg, p->memno, q->memoffset))
                   1698:            q->refs--;
                   1699: 
                   1700:   allset = YES;
                   1701:   return;
                   1702: }
                   1703: 
                   1704: 
                   1705: 
                   1706: LOCAL int samevar(r1, r2)
                   1707: register REGDATA *r1;
                   1708: register REGNODE *r2;
                   1709: 
                   1710: {
                   1711:   if ((r1->vstg != r2->vstg) ||
                   1712:       (r1->memno != r2->memno) ||
                   1713:       (r1->isarrayarg != r2->isarrayarg))
                   1714:     return NO;
                   1715:   if (r1->isarrayarg)
                   1716:     return YES;
                   1717:   return (r1->memoffset == r2->memoffset);
                   1718: }
                   1719: 
                   1720: 
                   1721: 
                   1722: LOCAL entableaddr(p)
                   1723: ADDRNODE *p;
                   1724: 
                   1725: {
                   1726:   int refs;
                   1727:   Addrp ap;
                   1728:   register int i;
                   1729: 
                   1730:   if (p->vstg != STGARG)
                   1731:     {
                   1732:       currentaddr = p;
                   1733:       return;
                   1734:     }
                   1735: 
                   1736:   refs = p->refs;
                   1737:   if (refs <= 0) return;
                   1738: 
                   1739:   if (tabletop < 0)
                   1740:     tabletop = i = 0;
                   1741:   else if (refs > rt[tabletop]->refs)
                   1742:     {
                   1743:       if (tabletop + 1 < TABLELIMIT)
                   1744:        tabletop++;
                   1745:       else
                   1746:        {
                   1747:          frexpr(rt[tabletop]->stgp);
                   1748:          free((char *) rt[tabletop]);
                   1749:        }
                   1750: 
                   1751:       for (i = tabletop; i > 0; i--)
                   1752:        if (refs > rt[i - 1]->refs)
                   1753:          rt[i] = rt[i - 1];
                   1754:        else
                   1755:          break;
                   1756:     }
                   1757:   else if (tabletop + 1 < TABLELIMIT)
                   1758:     i = ++tabletop;
                   1759:   else
                   1760:     return;
                   1761: 
                   1762:   rt[i] = ALLOC(regdata);
                   1763:   rt[i]->vstg = p->vstg;
                   1764:   rt[i]->vtype = p->vtype;
                   1765:   rt[i]->memno = p->memno;
                   1766:   rt[i]->refs = refs;
                   1767:   rt[i]->isarrayarg = YES;
                   1768: 
                   1769:   return;
                   1770: }
                   1771: 
                   1772: 
                   1773: 
                   1774: 
                   1775: LOCAL entablevar(p)
                   1776: VARNODE *p;
                   1777: 
                   1778: {
                   1779:   int refs;
                   1780:   register int i;
                   1781: 
                   1782:   if (p->unusable) return;
                   1783:   refs = p->refs - loopcost;
                   1784:   if (refs <= 0) return;
                   1785: 
                   1786:   if (tabletop < 0)
                   1787:     tabletop = i = 0;
                   1788:   else if (refs > rt[tabletop]->refs
                   1789: #ifdef BUMPREALS       /* put floats last */
                   1790:     || currentaddr->vtype!=TYREAL && rt[tabletop]->vtype==TYREAL && !rt[tabletop]->isarrayarg
                   1791: #endif
                   1792:     ){
                   1793:       if (tabletop + 1 < TABLELIMIT)
                   1794:         tabletop++;
                   1795:       else
                   1796:        {
                   1797:          frexpr(rt[tabletop]->stgp);
                   1798:           free((char *) rt[tabletop]);
                   1799:        }
                   1800: 
                   1801:       for (i = tabletop; i > 0; i--)
                   1802:         if (refs > rt[i - 1]->refs
                   1803: #ifdef BUMPREALS       /* put floats last */
                   1804:          || currentaddr->vtype!=TYREAL && rt[i-1]->vtype==TYREAL && !rt[i-1]->isarrayarg
                   1805: #endif
                   1806:        )
                   1807:           rt[i] = rt[i - 1];
                   1808:         else
                   1809:           break;
                   1810:     }
                   1811:   else if (tabletop + 1 < TABLELIMIT)
                   1812:     i = ++tabletop;
                   1813:   else
                   1814:     return;
                   1815: 
                   1816:   rt[i] = ALLOC(regdata);
                   1817:   rt[i]->vstg = currentaddr->vstg;
                   1818:   rt[i]->vtype = currentaddr->vtype;
                   1819:   rt[i]->memno = currentaddr->memno;
                   1820:   rt[i]->memoffset = p->memoffset;
                   1821:   rt[i]->refs = refs;
                   1822:   rt[i]->stgp = (Addrp) cpexpr(p->stgp);
                   1823:   rt[i]->isarrayarg = NO;
                   1824:   rt[i]->istemp = currentaddr->istemp;
                   1825:   rt[i]->isset = p->isset;
                   1826:   rt[i]->setfirst = p->setfirst;
                   1827: 
                   1828:   return;
                   1829: }
                   1830: 
                   1831: 
                   1832: 
                   1833: LOCAL int inregtab(p)
                   1834: register REGDATA *p;
                   1835: 
                   1836: {
                   1837:   register REGDATA *rp;
                   1838:   register int i;
                   1839: 
                   1840:   for (i = 0; i <= topregvar; i++)
                   1841:     if (rp = regtab[i])
                   1842:       if ((rp->vstg == p->vstg) &&
                   1843:          (rp->memno == p->memno) &&
                   1844:          (rp->isarrayarg == p->isarrayarg))
                   1845:        if (rp->isarrayarg)
                   1846:           return YES;
                   1847:         else if (rp->memoffset == p->memoffset)
                   1848:           return YES;
                   1849: 
                   1850:   return NO;
                   1851: }
                   1852: 
                   1853: 
                   1854: 
                   1855: LOCAL changetoreg(ap, i)
                   1856: register Addrp ap;
                   1857: int i;
                   1858: 
                   1859: {
                   1860:   ap->vstg = STGREG;
                   1861:   ap->memno = regnum[i];
                   1862:   frexpr(ap->memoffset);
                   1863:   ap->memoffset = ICON(0);
                   1864:   ap->istemp = NO;
                   1865:   return;
                   1866: }
                   1867: 
                   1868: 
                   1869: 
                   1870: LOCAL insertassign(sp, dest, src)
                   1871: Slotp sp;
                   1872: Addrp dest;
                   1873: expptr src;
                   1874: 
                   1875: {
                   1876:   Slotp newslot;
                   1877:   expptr p;
                   1878: 
                   1879:   p = mkexpr(OPASSIGN, dest, src);
                   1880:   newslot = optinsert (SKEQ,p,0,0,sp);
                   1881: 
                   1882:   if (sp == dohead)
                   1883:     if (!newcode)
                   1884:       newcode = newslot;
                   1885: 
                   1886:   return;
                   1887: }
                   1888: 
                   1889: 
                   1890: LOCAL appendassign(sp, dest, src)
                   1891: Slotp sp;
                   1892: Addrp dest;
                   1893: expptr src;
                   1894: 
                   1895: {
                   1896:   Slotp newslot;
                   1897:   expptr p;
                   1898: 
                   1899:   if (!sp)
                   1900:     fatal ("regalloc:appendassign");
                   1901: 
                   1902:   p = mkexpr(OPASSIGN, dest, src);
                   1903:   newslot = optinsert (SKEQ,p,0,0,sp->next);
                   1904: 
                   1905:   return;
                   1906: }
                   1907: 
                   1908: 
                   1909: 
                   1910: LOCAL int regtomem(sp)
                   1911: Slotp sp;
                   1912: 
                   1913: {
                   1914:   expptr p, l, r;
                   1915:   int i;
                   1916: 
                   1917:   if (sp->type != SKEQ) return NO;
                   1918: 
                   1919:   p = sp->expr;
                   1920:   if ((p->tag != TEXPR) || (p->exprblock.opcode != OPASSIGN))
                   1921:     return NO;
                   1922: 
                   1923:   r = p->exprblock.rightp;
                   1924:   if ((r->tag != TADDR) || (r->addrblock.vstg != STGREG))
                   1925:     return NO;
                   1926: 
                   1927:   l = p->exprblock.leftp;
                   1928:   if (l->tag != TADDR)
                   1929:     return NO;
                   1930:   i = r->addrblock.memno;
                   1931:   if (regtab[i] &&
                   1932:       (l->addrblock.vstg == regtab[i]->vstg) &&
                   1933:       (l->addrblock.memno == regtab[i]->memno) &&
                   1934:       fixedaddress(l) &&
                   1935:       (l->addrblock.memoffset->constblock.const.ci == regtab[i]->memoffset))
                   1936:     return YES;
                   1937: 
                   1938:   return NO;
                   1939: }
                   1940: 
                   1941: 
                   1942: 
                   1943: LOCAL int regtoreg(sp)
                   1944: Slotp sp;
                   1945: 
                   1946: {
                   1947:   expptr p, l, r;
                   1948: 
                   1949:   if (sp->type != SKEQ) return NO;
                   1950: 
                   1951:   p = sp->expr;
                   1952:   if ((p->tag != TEXPR) || (p->exprblock.opcode != OPASSIGN))
                   1953:     return NO;
                   1954: 
                   1955:   l = p->exprblock.leftp;
                   1956:   if ((l->tag != TADDR) || (l->addrblock.vstg != STGREG))
                   1957:     return NO;
                   1958: 
                   1959:   r = p->exprblock.rightp;
                   1960:   if ((r->tag == TADDR) &&
                   1961:       (r->addrblock.vstg == STGREG) &&
                   1962:       (r->addrblock.memno == l->addrblock.memno))
                   1963:     return YES;
                   1964: 
                   1965:   if ((r->tag == TEXPR) && 
                   1966:       (r->exprblock.opcode == OPADDR) &&
                   1967:       (r->exprblock.leftp->tag == TADDR) && 
                   1968:       (r->exprblock.leftp->addrblock.vstg == STGPREG) &&
                   1969:       (r->exprblock.leftp->addrblock.memno == l->addrblock.memno))
                   1970:       return YES;
                   1971: 
                   1972:   return NO;
                   1973: }
                   1974: 
                   1975: 
                   1976: 
                   1977: LOCAL deleteslot(sp)
                   1978: Slotp sp;
                   1979: 
                   1980: {
                   1981:   if (newcode == sp)
                   1982:     {
                   1983:       newcode = sp->next;
                   1984:       if (newcode == dohead)
                   1985:        newcode = NULL;
                   1986:     }
                   1987: 
                   1988:   delslot (sp);
                   1989:   return;
                   1990: }
                   1991: 
                   1992: 
                   1993: 
                   1994: LOCAL gensetall(sp)
                   1995: Slotp sp;
                   1996: 
                   1997: {
                   1998:   register int i;
                   1999:   register REGDATA *rp;
                   2000:   register Addrp ap;
                   2001: 
                   2002:   for (i = toplcv + 1; i <= topregvar; i++)
                   2003:     if (rp = regtab[i])
                   2004:       if (rp->isset && !(rp->istemp || rp->isarrayarg))
                   2005:        if (!memdefined[i])
                   2006:          {
                   2007:            ap = (Addrp) cpexpr(rp->stgp);
                   2008:            changetoreg(ap, i);
                   2009:            insertassign(sp, cpexpr(rp->stgp), ap);
                   2010:            memdefined[i] = YES;
                   2011:          }
                   2012: 
                   2013:   return;
                   2014: }
                   2015: 
                   2016: 
                   2017: LOCAL gensetcommon(sp)
                   2018: Slotp sp;
                   2019: 
                   2020: {
                   2021:   register int i;
                   2022:   register REGDATA *rp;
                   2023:   register Addrp ap;
                   2024: 
                   2025:   for (i = toplcv + 1; i <= topregvar; i++)
                   2026:     if (rp = regtab[i])
                   2027:       if ((rp->vstg == STGCOMMON) && !rp->isarrayarg)
                   2028:        if (!memdefined[i])
                   2029:          {
                   2030:            ap = (Addrp) cpexpr(rp->stgp);
                   2031:            changetoreg(ap, i);
                   2032:            insertassign(sp, cpexpr(rp->stgp), ap);
                   2033:            memdefined[i] = YES;
                   2034:          }
                   2035: 
                   2036:   return;
                   2037: }
                   2038: 
                   2039: 
                   2040: LOCAL gensetreturn(sp)
                   2041: Slotp sp;
                   2042: 
                   2043: {
                   2044:   register int i;
                   2045:   register REGDATA *rp;
                   2046:   register Addrp ap;
                   2047: 
                   2048:   for (i = toplcv + 1; i <= topregvar; i++)
                   2049:     if (rp = regtab[i])
                   2050:       if (((rp->vstg == STGCOMMON) && !rp->isarrayarg)
                   2051:       || (rp->isset && (saveall || rp->stgp->issaved) && !(rp->istemp || rp->isarrayarg)))
                   2052:        if (!memdefined[i])
                   2053:          {
                   2054:            ap = (Addrp) cpexpr(rp->stgp);
                   2055:            changetoreg(ap, i);
                   2056:            insertassign(sp, cpexpr(rp->stgp), ap);
                   2057:            memdefined[i] = YES;
                   2058:          }
                   2059: 
                   2060:   return;
                   2061: }
                   2062: 
                   2063: 
                   2064: 
                   2065: LOCAL clearmems()
                   2066: 
                   2067: {
                   2068:   REGDATA *rp;
                   2069:   register int i;
                   2070: 
                   2071:   for (i = 0; i <= toplcv; i++)
                   2072:     memdefined[i] = YES;
                   2073:   for (; i <= topregvar; i++)
                   2074:     if ((rp = regtab[i]) && rp->isset)
                   2075:       memdefined[i] = NO;
                   2076:     else
                   2077:       memdefined[i] = YES;
                   2078:   return;
                   2079: }
                   2080: 
                   2081: 
                   2082: LOCAL setregs()
                   2083: 
                   2084: {
                   2085:   register int i;
                   2086: 
                   2087:   for (i = 0; i <= topregvar; i++)
                   2088:     regdefined[i] = YES;
                   2089:   return;
                   2090: }
                   2091: 
                   2092: 
                   2093: 
                   2094: regalloc()
                   2095: 
                   2096: {
                   2097: int    match;
                   2098: Slotp  nextslot;
                   2099: Slotp  sl1,sl2;
                   2100: Slotp  lastlabslot;
                   2101: 
                   2102: if (! optimflag) return;
                   2103: 
                   2104: docount = 0;
                   2105: lastlabslot = NULL;
                   2106: for (sl1 = firstslot; sl1; sl1 = nextslot)
                   2107:        {
                   2108:        nextslot = sl1->next;
                   2109:        switch (sl1->type)
                   2110:            {
                   2111: 
                   2112: /* temporarily commented out -----
                   2113:            case SKLABEL:
                   2114:                lastlabslot = sl1;
                   2115:                break;
                   2116: 
                   2117:            case SKGOTO:
                   2118:                if (lastlabslot && sl1->label == lastlabslot->label)
                   2119:                        {
                   2120:                        dohead = lastlabslot;
                   2121:                        doend = sl1;
                   2122:                        alreg ();
                   2123:                        }
                   2124:                break;
                   2125: ----- */
                   2126: 
                   2127:            case SKDOHEAD:
                   2128:                ++docount;
                   2129:                pushq (sl1);
                   2130:                break;
                   2131: 
                   2132:            case SKENDDO:
                   2133:                --docount;
                   2134:                match = 0;
                   2135:                for (sl2 = sl1; sl2; sl2 = sl2->prev)
                   2136:                        {
                   2137:                        if (sl2->type == SKDOHEAD) match++;
                   2138:                        else if (sl2->type == SKENDDO) match--;
                   2139:                        if (match == 0) break;
                   2140:                        }
                   2141:                if (sl2)
                   2142:                        dohead = sl2;
                   2143:                else
                   2144:                        fatal ("unmatched enddo in code buffer");
                   2145:                if (sl2->type != SKDOHEAD)
                   2146:                        fatal ("internal error in regalloc");
                   2147: 
                   2148:                for (dqptr = dqbottom; dqptr; dqptr = dqptr->up)
                   2149:                        {
                   2150:                        if (dqptr->dohead == dohead)
                   2151:                                break;
                   2152:                        }
                   2153: 
                   2154:                if (!dqptr)
                   2155:                        fatal ("garbled doqueue in regalloc");
                   2156: 
                   2157:                /*  sl1 now points to the SKENDDO slot; the SKNULL slot
                   2158:                 *  is reached through sl1->nullslot
                   2159:                 */
                   2160:                dqptr->doend = (Slotp) sl1->nullslot;
                   2161:                if (docount == 0)
                   2162:                        {
                   2163:                        for (dqptr = dqbottom; dqptr; dqptr = dqptr->up)
                   2164:                                {
                   2165:                                dohead = dqptr->dohead;
                   2166:                                doend = dqptr->doend;
                   2167:                                alreg();
                   2168:                                }
                   2169:                        while (dqtop)
                   2170:                                popq(dqtop->dohead);
                   2171:                        docount = 0;
                   2172:                        }
                   2173:                break;
                   2174: 
                   2175:            default:
                   2176:                break;
                   2177:            }
                   2178:        }
                   2179: 
                   2180: return;
                   2181: }
                   2182: 
                   2183: 
                   2184: 
                   2185: LOCAL pushq(sp)
                   2186: Slotp sp;
                   2187: 
                   2188: {
                   2189:   DOQUEUE *t;
                   2190: 
                   2191:   if (sp->type != SKDOHEAD)
                   2192:     fatal("regalloc:pushq:  DO statement expected");
                   2193: 
                   2194:   if (dqbottom)
                   2195:     {
                   2196:       t = ALLOC(doqueue);
                   2197:       t->up = dqbottom;
                   2198:       dqbottom->down = t;
                   2199:       dqbottom = t;
                   2200:     }
                   2201:   else
                   2202:     dqtop = dqbottom = ALLOC(doqueue);
                   2203: 
                   2204:   dqbottom->dohead = sp;
                   2205: }
                   2206: 
                   2207: 
                   2208: LOCAL popq(sp)
                   2209: Slotp sp;
                   2210: 
                   2211: {
                   2212:   DOQUEUE *t;
                   2213:   register int i;
                   2214: 
                   2215:   if (!dqtop)
                   2216:     fatal("regalloc:popq:  empty DO queue");
                   2217:   if (dqtop->dohead != sp)
                   2218:     fatal("regalloc:popq:  garbled DO queue");
                   2219: 
                   2220:   t = dqtop;
                   2221:   
                   2222:   dqtop = t->down;
                   2223:   if (dqtop)
                   2224:     dqtop->up = NULL;
                   2225:   else
                   2226:     dqbottom = NULL;
                   2227:   for (i = 0; i < MAXREGVAR; i++)
                   2228:     if (t->reg[i])
                   2229:       free((char *) t->reg[i]);
                   2230:   free(t);
                   2231: }

unix.superglobalmegacorp.com

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