xref: /csrg-svn/usr.bin/f77/pass1.vax/bb.c (revision 22798)
1*22798Smckusick /*
2*22798Smckusick  * Copyright (c) 1980 Regents of the University of California.
3*22798Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*22798Smckusick  * specifies the terms and conditions for redistribution.
5*22798Smckusick  */
6*22798Smckusick 
7*22798Smckusick #ifndef lint
8*22798Smckusick static char sccsid[] = "@(#)bb.c	5.1 (Berkeley) 06/07/85";
9*22798Smckusick #endif not lint
10*22798Smckusick 
11*22798Smckusick /*
12*22798Smckusick  * bb.c
13*22798Smckusick  *
14*22798Smckusick  * Basic block optimizations.
15*22798Smckusick  *
16*22798Smckusick  * University of Utah CS Dept modification history:
17*22798Smckusick  *
18*22798Smckusick  * Revision 2.1  84/07/19  12:01:20  donn
19*22798Smckusick  * Changed comment headers for UofU.
20*22798Smckusick  *
21*22798Smckusick  * Revision 1.2  84/04/02  14:22:49  donn
22*22798Smckusick  * Bug in copy propagation missed places where temporaries are assigned to
23*22798Smckusick  * by OPSTAREQ or OPPLUSEQ, e.g. exponentiation with an integer constant
24*22798Smckusick  * power, expanded inline.
25*22798Smckusick  *
26*22798Smckusick  */
27*22798Smckusick 
28*22798Smckusick #include "defs.h"
29*22798Smckusick #include "optim.h"
30*22798Smckusick 
31*22798Smckusick /*
32*22798Smckusick  *  This file contains code for determination of basic blocks,
33*22798Smckusick  *  as well as some other optimization supporting routines
34*22798Smckusick  *  [including the main routine 'optimize()'].
35*22798Smckusick  *
36*22798Smckusick  *  The compiler's general debugging flag ['debugflag'] has been
37*22798Smckusick  *  extended to provide the capability of having multiple flags
38*22798Smckusick  *  which are contained in an array.  If the option -d is used,
39*22798Smckusick  *  then the flag debugflag[0] is set.  If a sequence of one or more
40*22798Smckusick  *  numbers are given (e.g, -d3,7,12), then the flags debugflag[3],
41*22798Smckusick  *  debugflag[7], and debugflag[12] are set.  The maximum number of
42*22798Smckusick  *  flags available is specified in the defines.h file.
43*22798Smckusick  */
44*22798Smckusick 
45*22798Smckusick 
46*22798Smckusick Bblockp	firstblock = NULL;		/* first block in buffer */
47*22798Smckusick Bblockp	lastblock = NULL;		/* last block in buffer */
48*22798Smckusick 
49*22798Smckusick expptr	tempalloc();
50*22798Smckusick 
51*22798Smckusick 
52*22798Smckusick optimize ()
53*22798Smckusick 
54*22798Smckusick {
55*22798Smckusick Bblockp bb;
56*22798Smckusick Slotp	sl,nextsl;
57*22798Smckusick 
58*22798Smckusick if (debugflag[2]) showbuffer ();
59*22798Smckusick 
60*22798Smckusick optloops ();
61*22798Smckusick 
62*22798Smckusick if (debugflag[3]) showbuffer ();
63*22798Smckusick 
64*22798Smckusick formbblock ();
65*22798Smckusick optcse ();
66*22798Smckusick 
67*22798Smckusick if (debugflag[4]) showbuffer ();
68*22798Smckusick 
69*22798Smckusick if (! debugflag[7])
70*22798Smckusick 	copyprop ();
71*22798Smckusick 
72*22798Smckusick if (debugflag[9]) showbuffer ();
73*22798Smckusick 
74*22798Smckusick for (sl = firstslot; sl; sl = nextsl)
75*22798Smckusick 	{
76*22798Smckusick 	nextsl = sl->next;
77*22798Smckusick 	if (sl->type == SKFRTEMP)
78*22798Smckusick 		{
79*22798Smckusick 		templist = mkchain (sl->expr,templist);
80*22798Smckusick 		sl->expr = NULL;
81*22798Smckusick 		delslot (sl);
82*22798Smckusick 		}
83*22798Smckusick 	else
84*22798Smckusick 		sl->expr = tempalloc (sl->expr);
85*22798Smckusick 	}
86*22798Smckusick 
87*22798Smckusick if (! debugflag[10])
88*22798Smckusick 	regalloc ();
89*22798Smckusick 
90*22798Smckusick flushopt ();
91*22798Smckusick }
92*22798Smckusick 
93*22798Smckusick 
94*22798Smckusick 
95*22798Smckusick /*
96*22798Smckusick  *  creates a new basic block record
97*22798Smckusick  */
98*22798Smckusick 
99*22798Smckusick LOCAL Bblockp newblock (sl)
100*22798Smckusick Slotp	sl;
101*22798Smckusick 
102*22798Smckusick {
103*22798Smckusick register Bblockp bb;
104*22798Smckusick 
105*22798Smckusick bb = ALLOC( bblock );
106*22798Smckusick bb->next = NULL ;
107*22798Smckusick if (lastblock)
108*22798Smckusick 	{
109*22798Smckusick 	bb->prev = lastblock;
110*22798Smckusick 	lastblock->next = bb;
111*22798Smckusick 	lastblock = bb;
112*22798Smckusick 	}
113*22798Smckusick else
114*22798Smckusick 	{
115*22798Smckusick 	firstblock = lastblock = bb;
116*22798Smckusick 	bb->prev = NULL;
117*22798Smckusick 	}
118*22798Smckusick 
119*22798Smckusick bb->first = sl;
120*22798Smckusick return (bb);
121*22798Smckusick }
122*22798Smckusick 
123*22798Smckusick 
124*22798Smckusick 
125*22798Smckusick /*
126*22798Smckusick  *  scans slot buffer, creating basic block records
127*22798Smckusick  */
128*22798Smckusick 
129*22798Smckusick formbblock ()
130*22798Smckusick 
131*22798Smckusick {
132*22798Smckusick Slotp	sl;
133*22798Smckusick field	type;
134*22798Smckusick Bblockp	newbb;
135*22798Smckusick 
136*22798Smckusick newbb = NULL;
137*22798Smckusick for (sl = firstslot; sl; sl = sl->next)
138*22798Smckusick 	{
139*22798Smckusick 	type = sl->type;
140*22798Smckusick 	switch (type)
141*22798Smckusick 		{
142*22798Smckusick 		case SKEQ:
143*22798Smckusick 			if (!newbb)
144*22798Smckusick 				newbb = newblock(sl);
145*22798Smckusick 			if (containscall(sl->expr))
146*22798Smckusick 				{
147*22798Smckusick 				newbb->last = sl;
148*22798Smckusick 				newbb = NULL;
149*22798Smckusick 				}
150*22798Smckusick 			break;
151*22798Smckusick 		case SKNULL:
152*22798Smckusick 		case SKASSIGN:
153*22798Smckusick 		case SKFRTEMP:
154*22798Smckusick 			if (!newbb)
155*22798Smckusick 				newbb = newblock(sl);
156*22798Smckusick 			break;
157*22798Smckusick 		case SKPAUSE:
158*22798Smckusick 		case SKSTOP:
159*22798Smckusick 		case SKIFN:
160*22798Smckusick 		case SKGOTO:
161*22798Smckusick 		case SKCMGOTO:
162*22798Smckusick 		case SKARIF:
163*22798Smckusick 		case SKASGOTO:
164*22798Smckusick 		case SKIOIFN:
165*22798Smckusick 		case SKCALL:
166*22798Smckusick 		case SKRETURN:
167*22798Smckusick 			if (!newbb)
168*22798Smckusick 				newbb = newblock(sl);
169*22798Smckusick 			newbb->last = sl;
170*22798Smckusick 			newbb = NULL;
171*22798Smckusick 			break;
172*22798Smckusick 		case SKLABEL:
173*22798Smckusick 			if (newbb)
174*22798Smckusick 				newbb->last = sl->prev;
175*22798Smckusick 			newbb = newblock(sl);
176*22798Smckusick 			break;
177*22798Smckusick 		case SKDOHEAD:
178*22798Smckusick 		case SKENDDO:
179*22798Smckusick 			if (!newbb)
180*22798Smckusick 				newbb = newblock(sl);
181*22798Smckusick 			break;
182*22798Smckusick 		default:
183*22798Smckusick 			badthing("SKtype", "formbblock", type);
184*22798Smckusick 			break;
185*22798Smckusick 		}
186*22798Smckusick 	}
187*22798Smckusick if (newbb)
188*22798Smckusick 	newbb->last = lastslot;
189*22798Smckusick }
190*22798Smckusick 
191*22798Smckusick 
192*22798Smckusick 
193*22798Smckusick /*
194*22798Smckusick  *  frees all basic block records
195*22798Smckusick  *  as well as the id and value node chains hanging off the bb and their
196*22798Smckusick  *  respective cross link chains (IDlist, DUPlist and NODElist structs)
197*22798Smckusick  */
198*22798Smckusick 
199*22798Smckusick clearbb ()
200*22798Smckusick {
201*22798Smckusick Bblockp	bb,next;
202*22798Smckusick 
203*22798Smckusick for (bb = firstblock; bb; bb = next)
204*22798Smckusick 	{
205*22798Smckusick 	next = bb->next;
206*22798Smckusick 	   {
207*22798Smckusick 	     idptr idp,next;
208*22798Smckusick 	     for(idp = bb->headid; idp; idp = next)
209*22798Smckusick 		{
210*22798Smckusick 		 next = idp->next;
211*22798Smckusick 		      {
212*22798Smckusick 		      nodelptr nodelp, next;
213*22798Smckusick 	              for(nodelp = idp->headnodelist; nodelp; nodelp = next)
214*22798Smckusick 			 {
215*22798Smckusick 			    next = nodelp->next;
216*22798Smckusick 		            free( (charptr) nodelp);
217*22798Smckusick 		         }
218*22798Smckusick 		      }
219*22798Smckusick                  free( (charptr) idp);
220*22798Smckusick 	        }
221*22798Smckusick            }
222*22798Smckusick 	   {
223*22798Smckusick 	     valuen vp,next;
224*22798Smckusick 	     for(vp = bb->headnode; vp; vp = next)
225*22798Smckusick 		{
226*22798Smckusick 		 next = vp->next;
227*22798Smckusick 		      {
228*22798Smckusick 		      idlptr idlp, next;
229*22798Smckusick 	              for(idlp = vp->headdeplist; idlp; idlp = next)
230*22798Smckusick 			 {
231*22798Smckusick 			    next = idlp->next;
232*22798Smckusick 		            free( (charptr) idlp);
233*22798Smckusick 		         }
234*22798Smckusick 		      }
235*22798Smckusick 		      {
236*22798Smckusick 		      duplptr duplp, next;
237*22798Smckusick 	              for(duplp = vp->headduplist; duplp; duplp = next)
238*22798Smckusick 			 {
239*22798Smckusick 			    next = duplp->next;
240*22798Smckusick 		            free( (charptr) duplp);
241*22798Smckusick 		         }
242*22798Smckusick 		      }
243*22798Smckusick                  free( (charptr) vp);
244*22798Smckusick 	        }
245*22798Smckusick            }
246*22798Smckusick 	free ( (charptr) bb);
247*22798Smckusick 	}
248*22798Smckusick firstblock = lastblock = NULL;
249*22798Smckusick }
250*22798Smckusick 
251*22798Smckusick 
252*22798Smckusick /* structure for maintaining records on copy statements */
253*22798Smckusick 
254*22798Smckusick typedef struct Subrec {
255*22798Smckusick 	Addrp	lmem;
256*22798Smckusick 	Addrp	rmem;
257*22798Smckusick 	int	sets;
258*22798Smckusick } *Subrecp;
259*22798Smckusick 
260*22798Smckusick 
261*22798Smckusick LOCAL chainp sublist;	/* list of copy statements */
262*22798Smckusick LOCAL int prop1count;	/* count of number of temporaries eliminated */
263*22798Smckusick LOCAL int prop2count;	/* count of number of uses of temporaries replaced */
264*22798Smckusick 
265*22798Smckusick expptr rmcommaop();
266*22798Smckusick Addrp subfor();
267*22798Smckusick 
268*22798Smckusick 
269*22798Smckusick 
270*22798Smckusick /*
271*22798Smckusick  *  eliminates copy statements of the form T1 = T2 from the intermediate
272*22798Smckusick  *  code, where T1 and T2 are temporary variables which are each
273*22798Smckusick  *  set only once;  eliminates the copy statement and replaces each
274*22798Smckusick  *  use of T1 by T2 (T1 is therefore totally eliminated).
275*22798Smckusick  */
276*22798Smckusick 
277*22798Smckusick LOCAL copyprop ()
278*22798Smckusick 
279*22798Smckusick {
280*22798Smckusick Slotp	sl,nextsl;
281*22798Smckusick expptr	expr;
282*22798Smckusick Tempp	lp,rp;
283*22798Smckusick 
284*22798Smckusick for (sl = firstslot; sl; sl = sl->next)
285*22798Smckusick 	sl->expr = rmcommaop (sl->expr,sl);
286*22798Smckusick 
287*22798Smckusick prop1count = prop2count = 0;
288*22798Smckusick findcopies ();
289*22798Smckusick 
290*22798Smckusick for (sl = firstslot; sl; sl = nextsl)
291*22798Smckusick 	{
292*22798Smckusick 	nextsl = sl->next;
293*22798Smckusick 	expr = sl->expr;
294*22798Smckusick 
295*22798Smckusick 	if ((sl->type == SKFRTEMP) && subfor (expr))
296*22798Smckusick 		{
297*22798Smckusick 		delslot (sl);
298*22798Smckusick 		expr = ENULL;
299*22798Smckusick 		}
300*22798Smckusick 	else if (expr && expr->tag == TEXPR &&
301*22798Smckusick 			expr->exprblock.opcode == OPASSIGN)
302*22798Smckusick 		{
303*22798Smckusick 		lp = (Tempp) expr->exprblock.leftp;
304*22798Smckusick 		rp = (Tempp) expr->exprblock.rightp;
305*22798Smckusick 		if (lp->tag == TTEMP && rp->tag == TTEMP)
306*22798Smckusick 			if (subfor(lp->memalloc) == rp->memalloc
307*22798Smckusick 					&& !subfor (rp->memalloc))
308*22798Smckusick 				{
309*22798Smckusick 				frexpr (expr);
310*22798Smckusick 				expr = sl->expr = ENULL;
311*22798Smckusick 				prop1count++;
312*22798Smckusick 				}
313*22798Smckusick 		}
314*22798Smckusick 
315*22798Smckusick 	propagate (expr);
316*22798Smckusick 	}
317*22798Smckusick 
318*22798Smckusick if (debugflag[0])
319*22798Smckusick 	fprintf (diagfile,
320*22798Smckusick 	    "%d temporarie%s replaced by copy propagation (%d use%s)\n",
321*22798Smckusick 		prop1count,(prop1count==1 ? "" : "s"),
322*22798Smckusick 		prop2count,(prop2count==1 ? "" : "s") );
323*22798Smckusick }
324*22798Smckusick 
325*22798Smckusick 
326*22798Smckusick 
327*22798Smckusick /*
328*22798Smckusick  *  finds copy statements and enters information in table
329*22798Smckusick  */
330*22798Smckusick 
331*22798Smckusick LOCAL findcopies ()
332*22798Smckusick 
333*22798Smckusick {
334*22798Smckusick Slotp	sl;
335*22798Smckusick expptr	expr;
336*22798Smckusick chainp	cp;
337*22798Smckusick 
338*22798Smckusick for (sl = firstslot; sl; sl = sl->next)
339*22798Smckusick 	{
340*22798Smckusick 	expr = sl->expr;
341*22798Smckusick 	if (expr) switch (expr->tag)
342*22798Smckusick 	    {
343*22798Smckusick 	    case TEXPR:
344*22798Smckusick 		ckexpr (expr);
345*22798Smckusick 		break;
346*22798Smckusick 
347*22798Smckusick 	    case TLIST:
348*22798Smckusick 		for (cp = expr->listblock.listp; cp; cp = cp->nextp)
349*22798Smckusick 			{
350*22798Smckusick 			expr = (expptr) cp->datap;
351*22798Smckusick 			ckexpr (expr);
352*22798Smckusick 			}
353*22798Smckusick 		break;
354*22798Smckusick 
355*22798Smckusick 	    default:
356*22798Smckusick 		break;
357*22798Smckusick 	    }
358*22798Smckusick 	}
359*22798Smckusick }
360*22798Smckusick 
361*22798Smckusick 
362*22798Smckusick 
363*22798Smckusick /*
364*22798Smckusick  *  checks an individual expression
365*22798Smckusick  */
366*22798Smckusick 
367*22798Smckusick ckexpr (expr)
368*22798Smckusick expptr	expr;
369*22798Smckusick 
370*22798Smckusick {
371*22798Smckusick Tempp	lp,rp;
372*22798Smckusick int	oc = expr->exprblock.opcode;
373*22798Smckusick 
374*22798Smckusick if (oc == OPASSIGN || oc == OPPLUSEQ || oc == OPSTAREQ)
375*22798Smckusick 	{
376*22798Smckusick 	lp = (Tempp) expr->exprblock.leftp;
377*22798Smckusick 	rp = (Tempp) expr->exprblock.rightp;
378*22798Smckusick 	if (lp->tag == TTEMP)
379*22798Smckusick 		if (rp->tag == TTEMP && oc == OPASSIGN)
380*22798Smckusick 			enter (lp->memalloc, rp->memalloc);
381*22798Smckusick 		else
382*22798Smckusick 			enter (lp->memalloc, ENULL);
383*22798Smckusick 	}
384*22798Smckusick }
385*22798Smckusick 
386*22798Smckusick 
387*22798Smckusick 
388*22798Smckusick /*
389*22798Smckusick  *  Enters the given memalloc values in the table (or update if they
390*22798Smckusick  *  are already there), for the assignment statement m1 = m2.
391*22798Smckusick  *  If m2 is NULL, this indicates that the assignment is not a copy
392*22798Smckusick  *  statement.
393*22798Smckusick  */
394*22798Smckusick 
395*22798Smckusick LOCAL enter (m1,m2)
396*22798Smckusick Addrp	m1,m2;
397*22798Smckusick 
398*22798Smckusick {
399*22798Smckusick chainp	cp;
400*22798Smckusick Subrecp old,new;
401*22798Smckusick 
402*22798Smckusick for (cp = sublist; cp; cp = cp->nextp)
403*22798Smckusick 	{
404*22798Smckusick 	old = (Subrecp) cp->datap;
405*22798Smckusick 	if (old->lmem == m1)
406*22798Smckusick 		{
407*22798Smckusick 		old->sets++;
408*22798Smckusick 		return;
409*22798Smckusick 		}
410*22798Smckusick 	}
411*22798Smckusick 
412*22798Smckusick new = ALLOC (Subrec);
413*22798Smckusick new->lmem = m1;
414*22798Smckusick new->rmem = m2;
415*22798Smckusick new->sets = 1;
416*22798Smckusick sublist = mkchain (new, sublist);
417*22798Smckusick }
418*22798Smckusick 
419*22798Smckusick 
420*22798Smckusick 
421*22798Smckusick /*
422*22798Smckusick  *  looks for record for the given memalloc value
423*22798Smckusick  */
424*22798Smckusick 
425*22798Smckusick LOCAL Subrecp lookup (mem)
426*22798Smckusick Addrp	mem;
427*22798Smckusick 
428*22798Smckusick {
429*22798Smckusick chainp	cp;
430*22798Smckusick Subrecp rec;
431*22798Smckusick 
432*22798Smckusick for (cp = sublist; cp; cp = cp->nextp)
433*22798Smckusick 	{
434*22798Smckusick 	rec = (Subrecp) cp->datap;
435*22798Smckusick 	if (rec->lmem == mem)
436*22798Smckusick 		return rec;
437*22798Smckusick 	}
438*22798Smckusick 
439*22798Smckusick return NULL;
440*22798Smckusick }
441*22798Smckusick 
442*22798Smckusick 
443*22798Smckusick 
444*22798Smckusick /*
445*22798Smckusick  *  checks to see if there is a substitute for given memalloc value
446*22798Smckusick  */
447*22798Smckusick 
448*22798Smckusick LOCAL Addrp subfor (mem)
449*22798Smckusick Addrp	mem;
450*22798Smckusick 
451*22798Smckusick {
452*22798Smckusick Subrecp rec,rec2;
453*22798Smckusick Addrp	sub;
454*22798Smckusick 
455*22798Smckusick rec = lookup (mem);
456*22798Smckusick if (rec && rec->sets == 1)
457*22798Smckusick 	{
458*22798Smckusick 	sub = rec->rmem;
459*22798Smckusick 	rec2 = lookup(sub);
460*22798Smckusick 	if (rec2 && rec2->sets == 1)
461*22798Smckusick 		return sub;
462*22798Smckusick 	}
463*22798Smckusick 
464*22798Smckusick return NULL;
465*22798Smckusick }
466*22798Smckusick 
467*22798Smckusick 
468*22798Smckusick 
469*22798Smckusick /*
470*22798Smckusick  *  actually propagates the information
471*22798Smckusick  */
472*22798Smckusick 
473*22798Smckusick LOCAL propagate (expr)
474*22798Smckusick expptr	expr;
475*22798Smckusick 
476*22798Smckusick {
477*22798Smckusick chainp	t;
478*22798Smckusick Addrp	new;
479*22798Smckusick 
480*22798Smckusick if (! expr) return;
481*22798Smckusick 
482*22798Smckusick switch (expr->tag)
483*22798Smckusick 	{
484*22798Smckusick 	case TEXPR:
485*22798Smckusick 		propagate (expr->exprblock.leftp);
486*22798Smckusick 		propagate (expr->exprblock.rightp);
487*22798Smckusick 		break;
488*22798Smckusick 
489*22798Smckusick 	case TADDR:
490*22798Smckusick 		propagate (expr->addrblock.vleng);
491*22798Smckusick 		propagate (expr->addrblock.memoffset);
492*22798Smckusick 		break;
493*22798Smckusick 
494*22798Smckusick 	case TLIST:
495*22798Smckusick 		for (t = expr->listblock.listp; t; t = t->nextp)
496*22798Smckusick 			propagate (t->datap);
497*22798Smckusick 		break;
498*22798Smckusick 
499*22798Smckusick 	case TTEMP:
500*22798Smckusick 		new = subfor (expr->tempblock.memalloc);
501*22798Smckusick 		if (new)
502*22798Smckusick 			{
503*22798Smckusick 			expr->tempblock.memalloc = new;
504*22798Smckusick 			prop2count++;
505*22798Smckusick 			}
506*22798Smckusick 		break;
507*22798Smckusick 
508*22798Smckusick 	default:
509*22798Smckusick 		break;
510*22798Smckusick 	}
511*22798Smckusick }
512*22798Smckusick 
513*22798Smckusick 
514*22798Smckusick 
515*22798Smckusick /*
516*22798Smckusick  *  allocates ADDR blocks for each TEMP in the expression
517*22798Smckusick  */
518*22798Smckusick 
519*22798Smckusick LOCAL expptr tempalloc (expr)
520*22798Smckusick expptr	expr;
521*22798Smckusick 
522*22798Smckusick {
523*22798Smckusick chainp	t;
524*22798Smckusick 
525*22798Smckusick if (! expr)
526*22798Smckusick 	return NULL;
527*22798Smckusick 
528*22798Smckusick switch (expr->tag)
529*22798Smckusick     {
530*22798Smckusick     case TEXPR:
531*22798Smckusick 	expr->exprblock.leftp = tempalloc (expr->exprblock.leftp);
532*22798Smckusick 	expr->exprblock.rightp = tempalloc (expr->exprblock.rightp);
533*22798Smckusick 	break;
534*22798Smckusick 
535*22798Smckusick     case TADDR:
536*22798Smckusick 	expr->addrblock.vleng = tempalloc (expr->addrblock.vleng);
537*22798Smckusick 	expr->addrblock.memoffset = tempalloc (expr->addrblock.memoffset);
538*22798Smckusick 	break;
539*22798Smckusick 
540*22798Smckusick     case TLIST:
541*22798Smckusick 	for (t = expr->listblock.listp; t; t = t->nextp)
542*22798Smckusick 		t->datap = (tagptr) tempalloc (t->datap);
543*22798Smckusick 	break;
544*22798Smckusick 
545*22798Smckusick     case TTEMP:
546*22798Smckusick 	return (expptr) cpexpr (altmpn (expr));
547*22798Smckusick 	break;
548*22798Smckusick 
549*22798Smckusick     default:
550*22798Smckusick 	break;
551*22798Smckusick     }
552*22798Smckusick return expr;
553*22798Smckusick }
554*22798Smckusick 
555*22798Smckusick 
556*22798Smckusick /********************* debugging routines *********************/
557*22798Smckusick 
558*22798Smckusick 
559*22798Smckusick 
560*22798Smckusick Announce (s,q)
561*22798Smckusick char *s;
562*22798Smckusick expptr q;
563*22798Smckusick 
564*22798Smckusick {
565*22798Smckusick fprintf (diagfile,"\nAn expression [%s]----->\n",s);
566*22798Smckusick showexpr(q,0);
567*22798Smckusick fprintf (diagfile,"\n-------------end of expr--------------\n");
568*22798Smckusick }
569*22798Smckusick 
570*22798Smckusick 
571*22798Smckusick 
572*22798Smckusick /*
573*22798Smckusick  *  dump the basic block buffer, including expressions, mnemonically
574*22798Smckusick  */
575*22798Smckusick 
576*22798Smckusick showbuffer ()
577*22798Smckusick 
578*22798Smckusick {
579*22798Smckusick Slotp	sl;
580*22798Smckusick Bblockp	bb;
581*22798Smckusick int	i;
582*22798Smckusick 
583*22798Smckusick fprintf (diagfile,"Basic blocks with first and last slots ----------\n");
584*22798Smckusick for (i=1, bb = firstblock; bb; i++, bb = bb->next)
585*22798Smckusick 	fprintf (diagfile,"%2d.  %d  %d\n",i,bb->first,bb->last);
586*22798Smckusick fprintf (diagfile,"\n");
587*22798Smckusick 
588*22798Smckusick fprintf (diagfile,"Slots and expressions ----------\n");
589*22798Smckusick 
590*22798Smckusick fprintf (diagfile,"tag pointer vtype vclass vstg vleng\n");
591*22798Smckusick fprintf (diagfile,"          ADDR memno memoffset istemp ntempelt varleng\n");
592*22798Smckusick fprintf (diagfile,"          TEMP memalloc istemp ntempelt varleng\n");
593*22798Smckusick fprintf (diagfile,"          EXPR opcode leftp rightp\n");
594*22798Smckusick fprintf (diagfile,"          LIST type listp\n");
595*22798Smckusick fprintf (diagfile,"\n");
596*22798Smckusick 
597*22798Smckusick for (i=1, sl = firstslot; sl; i++, sl = sl->next)
598*22798Smckusick 	{
599*22798Smckusick 	fprintf (diagfile,"%2d.  ",i);
600*22798Smckusick 	showslt (sl);
601*22798Smckusick 	}
602*22798Smckusick fprintf (diagfile,"---------- End of showbuffer ----------\n");
603*22798Smckusick }
604*22798Smckusick 
605*22798Smckusick 
606*22798Smckusick 
607*22798Smckusick /*
608*22798Smckusick  *  dumps a single slot in the code buffer
609*22798Smckusick  */
610*22798Smckusick 
611*22798Smckusick LOCAL charptr Zslot[] = {"NULL",
612*22798Smckusick 	"IFN","GOTO","LABEL","EQ","CALL","CMGOTO","STOP","DOHEAD",
613*22798Smckusick 	"ENDDO","ARIF","RETURN","ASGOTO","PAUSE","ASSIGN","IOIFN","FRTEMP"};
614*22798Smckusick 
615*22798Smckusick 
616*22798Smckusick 
617*22798Smckusick showslt (sl)
618*22798Smckusick Slotp sl;
619*22798Smckusick 
620*22798Smckusick {
621*22798Smckusick fprintf (diagfile,"(%2d)  %d  %s  %d\n",
622*22798Smckusick 	sl->lineno,sl,Zslot[sl->type],sl->label);
623*22798Smckusick showexpr (sl->expr,0);
624*22798Smckusick fprintf (diagfile,"\n");
625*22798Smckusick }
626*22798Smckusick 
627*22798Smckusick 
628*22798Smckusick 
629*22798Smckusick showslottype (type)
630*22798Smckusick int type;
631*22798Smckusick 
632*22798Smckusick {
633*22798Smckusick fprintf (diagfile,"%s\n",Zslot[type]);
634*22798Smckusick }
635*22798Smckusick 
636*22798Smckusick 
637*22798Smckusick 
638*22798Smckusick /*
639*22798Smckusick  *  displays the given expression at the given indentation, showing
640*22798Smckusick  *  its subexpressions at further indentations
641*22798Smckusick  */
642*22798Smckusick 
643*22798Smckusick LOCAL charptr Ztag[] = {"----",
644*22798Smckusick 	"NAME","CONST","EXPR","ADDR","TEMP","PRIM","LIST","IMPLDO","ERROR"};
645*22798Smckusick LOCAL charptr Zstg[] = {"unk",
646*22798Smckusick 	"ARG","AUTO","BSS","INIT","CONST","EXT","INTR","STFUNCT",
647*22798Smckusick 	"COMMON","EQUIV","REG","LENG","NULL","PREG"};
648*22798Smckusick LOCAL charptr Zclass[] = {"unk",
649*22798Smckusick 	"PARAM","VAR","ENTRY","MAIN","BLOCK","PROC","NAMELIST"};
650*22798Smckusick LOCAL charptr Zop[] = {"----",
651*22798Smckusick 	"PLUS","MINUS","STAR","SLASH","POWER","NEG","OR","AND","EQV",
652*22798Smckusick 	"NEQV","NOT","CONCAT","LT","EQ","GT","LE","NE","GE","CALL",
653*22798Smckusick 	"CCALL","ASSIGN","PLUSEQ","STAREQ","CONV","LSHIFT","MOD",
654*22798Smckusick 	"COMMA","QUEST","COLON","ABS","MIN","MAX","ADDR","INDIRECT",
655*22798Smckusick 	"BITOR","BITAND","BITXOR","BITNOT","RSHIFT","PAREN"};
656*22798Smckusick LOCAL charptr Ztype[] = {"unk",
657*22798Smckusick 	"ADDR","SHORT","LONG","REAL","DREAL","COMPLEX","DCOMPLEX",
658*22798Smckusick 	"LOGICAL","CHAR","SUBR","ERROR"};
659*22798Smckusick 
660*22798Smckusick 
661*22798Smckusick showexpr(p,indent)
662*22798Smckusick tagptr p;
663*22798Smckusick int indent;
664*22798Smckusick 
665*22798Smckusick {
666*22798Smckusick int i;
667*22798Smckusick int type;
668*22798Smckusick chainp q;
669*22798Smckusick 
670*22798Smckusick #define PRHEAD(q) fprintf(diagfile,"%s %d %s %s %s %d", \
671*22798Smckusick 	Ztag[q->tag], q, Ztype[q->headblock.vtype], \
672*22798Smckusick 	Zclass[q->headblock.vclass], Zstg[q->headblock.vstg], \
673*22798Smckusick 	q->headblock.vleng);
674*22798Smckusick #define SHOWEXPR(p) showexpr(p,indent+2)
675*22798Smckusick 
676*22798Smckusick 
677*22798Smckusick 
678*22798Smckusick if(p == NULL)
679*22798Smckusick 	return;
680*22798Smckusick 
681*22798Smckusick for (i=0; i<indent; i++)
682*22798Smckusick 	putc(' ',diagfile);
683*22798Smckusick 
684*22798Smckusick switch(p->tag)
685*22798Smckusick          {
686*22798Smckusick          case TCONST:
687*22798Smckusick               PRHEAD(p);
688*22798Smckusick 
689*22798Smckusick               type=p->constblock.vtype;
690*22798Smckusick               if (ISCHAR(p))
691*22798Smckusick                  {
692*22798Smckusick                       fprintf(diagfile," ISCHAR ccp= %d\n",
693*22798Smckusick                                                    p->constblock.const.ccp);
694*22798Smckusick                       SHOWEXPR(p->constblock.vleng);
695*22798Smckusick                  }
696*22798Smckusick               else  if( ISINT(type) )
697*22798Smckusick                    fprintf(diagfile," ci= %d\n",p->constblock.const.ci);
698*22798Smckusick               else if( ISREAL(type) )
699*22798Smckusick                    fprintf(diagfile," cd[0]= %e\n",p->constblock.const.cd[0]);
700*22798Smckusick               else fprintf(diagfile," cd[0]= %e  cd[1]= %e\n",
701*22798Smckusick                             p->constblock.const.cd[0],
702*22798Smckusick                             p->constblock.const.cd[1] );
703*22798Smckusick               break;
704*22798Smckusick 
705*22798Smckusick          case TADDR:
706*22798Smckusick               PRHEAD(p);
707*22798Smckusick               fprintf(diagfile,
708*22798Smckusick               " memno= %d %d %d %d %d\n",
709*22798Smckusick               p->addrblock.memno,p->addrblock.memoffset,p->addrblock.istemp,
710*22798Smckusick               p->addrblock.ntempelt,p->addrblock.varleng);
711*22798Smckusick               SHOWEXPR(p->addrblock.vleng);
712*22798Smckusick               SHOWEXPR(p->addrblock.memoffset);
713*22798Smckusick               break;
714*22798Smckusick 
715*22798Smckusick          case TTEMP:
716*22798Smckusick 	      fprintf(diagfile,"%s %d %s %s %d",
717*22798Smckusick 			Ztag[p->tag], p, Ztype[p->headblock.vtype],
718*22798Smckusick 			Zclass[p->headblock.vclass],
719*22798Smckusick 			p->headblock.vleng);
720*22798Smckusick               fprintf(diagfile,
721*22798Smckusick 		" memalloc= %d %d %d %d\n",
722*22798Smckusick 		p->tempblock.memalloc,p->tempblock.istemp,
723*22798Smckusick 		p->tempblock.ntempelt,p->tempblock.varleng);
724*22798Smckusick               SHOWEXPR(p->tempblock.vleng);
725*22798Smckusick 	      SHOWEXPR(p->tempblock.memalloc);
726*22798Smckusick               break;
727*22798Smckusick 
728*22798Smckusick          case TERROR:
729*22798Smckusick               fprintf(diagfile,"ERROR %d\n",p);
730*22798Smckusick               break;
731*22798Smckusick 
732*22798Smckusick          case TNAME:
733*22798Smckusick               fprintf(diagfile,"NAME %d\n",p);
734*22798Smckusick               return;
735*22798Smckusick 
736*22798Smckusick          case TPRIM:
737*22798Smckusick               fprintf(diagfile,"PRIM %d --- not implemented\n",p);
738*22798Smckusick               break;
739*22798Smckusick 
740*22798Smckusick          case TEXPR:
741*22798Smckusick               PRHEAD(p);
742*22798Smckusick               fprintf(diagfile," opcode= %s %d %d\n",
743*22798Smckusick                      Zop[p->exprblock.opcode],p->exprblock.leftp,
744*22798Smckusick                      p->exprblock.rightp);
745*22798Smckusick               SHOWEXPR(p->exprblock.leftp);
746*22798Smckusick               if(p->exprblock.rightp)
747*22798Smckusick                     SHOWEXPR(p->exprblock.rightp);
748*22798Smckusick               break;
749*22798Smckusick 
750*22798Smckusick          case TLIST:
751*22798Smckusick               fprintf(diagfile,"LIST %d %s %d\n",p,
752*22798Smckusick                       Ztype[p->listblock.vtype],p->listblock.listp);
753*22798Smckusick               for(q= p->listblock.listp ; q ; q = q->nextp)
754*22798Smckusick                       SHOWEXPR(q->datap);
755*22798Smckusick 	      for (i=0; i<indent; i++)
756*22798Smckusick 		putc (' ',diagfile);
757*22798Smckusick               fprintf(diagfile,"END LIST %d\n",p);
758*22798Smckusick               break;
759*22798Smckusick 
760*22798Smckusick          default:
761*22798Smckusick               fprintf(diagfile,"showexpr BAD TAG= %d at %d \n",p->tag,p);
762*22798Smckusick            }
763*22798Smckusick }
764*22798Smckusick 
765*22798Smckusick 
766*22798Smckusick 
767*22798Smckusick selective()/************************************/
768*22798Smckusick {
769*22798Smckusick int i;
770*22798Smckusick Slotp sl;
771*22798Smckusick 
772*22798Smckusick i=0;
773*22798Smckusick fprintf (stderr,"SELECTIVE OUTPUT\n");
774*22798Smckusick for (sl=firstslot;sl;sl=sl->next)
775*22798Smckusick 	{
776*22798Smckusick 	i++;
777*22798Smckusick 	if (i>=176 && i<184)
778*22798Smckusick 		{
779*22798Smckusick 		fprintf (stderr,"%d.  ",i);
780*22798Smckusick 		showslt(sl);
781*22798Smckusick 		}
782*22798Smckusick 	}
783*22798Smckusick }
784*22798Smckusick 
785*22798Smckusick 
786*22798Smckusick 
787*22798Smckusick 
788*22798Smckusick LOCAL containscall(p)
789*22798Smckusick expptr p;
790*22798Smckusick {
791*22798Smckusick   chainp cp;
792*22798Smckusick 
793*22798Smckusick   if (p == NULL)
794*22798Smckusick     return NO;
795*22798Smckusick 
796*22798Smckusick   switch (p->tag)
797*22798Smckusick     {
798*22798Smckusick     case TADDR:
799*22798Smckusick       if (containscall(p->addrblock.vleng)
800*22798Smckusick 	  || containscall(p->addrblock.memoffset))
801*22798Smckusick 	return YES;
802*22798Smckusick       else
803*22798Smckusick         return NO;
804*22798Smckusick 
805*22798Smckusick     case TCONST:
806*22798Smckusick       return NO;
807*22798Smckusick 
808*22798Smckusick     case TERROR:
809*22798Smckusick       return NO;
810*22798Smckusick 
811*22798Smckusick     case TEXPR:
812*22798Smckusick       if (p->exprblock.opcode == OPCALL ||
813*22798Smckusick 	  p->exprblock.opcode == OPCCALL)
814*22798Smckusick 	return YES;
815*22798Smckusick       if (containscall(p->exprblock.vleng) ||
816*22798Smckusick 	  containscall(p->exprblock.leftp) ||
817*22798Smckusick 	  containscall(p->exprblock.rightp))
818*22798Smckusick 	return YES;
819*22798Smckusick       else
820*22798Smckusick 	return NO;
821*22798Smckusick 
822*22798Smckusick     case TLIST:
823*22798Smckusick       cp = p->listblock.listp;
824*22798Smckusick       while (cp)
825*22798Smckusick 	{
826*22798Smckusick 	  if (containscall(cp->datap))
827*22798Smckusick 	    return YES;
828*22798Smckusick 	  cp = cp->nextp;
829*22798Smckusick 	}
830*22798Smckusick       return NO;
831*22798Smckusick 
832*22798Smckusick     default:
833*22798Smckusick       return YES;
834*22798Smckusick     }
835*22798Smckusick }
836