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