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