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