|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.