|
|
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.