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