xref: /csrg-svn/usr.bin/f77/pass1.tahoe/bb.c (revision 46301)
143202Sbostic /*
243202Sbostic  * Copyright (c) 1980 Regents of the University of California.
343202Sbostic  * All rights reserved.  The Berkeley software License Agreement
443202Sbostic  * specifies the terms and conditions for redistribution.
543202Sbostic  */
643202Sbostic 
743202Sbostic #ifndef lint
843202Sbostic static char sccsid[] = "@(#)bb.c	5.1 (Berkeley) 6/7/85";
943202Sbostic #endif not lint
1043202Sbostic 
1143202Sbostic /*
1243202Sbostic  * bb.c
1343202Sbostic  *
1443202Sbostic  * Basic block optimizations.
1543202Sbostic  *
1643202Sbostic  * University of Utah CS Dept modification history:
1743202Sbostic  *
1843202Sbostic  * Revision 2.1  84/07/19  12:01:20  donn
1943202Sbostic  * Changed comment headers for UofU.
2043202Sbostic  *
2143202Sbostic  * Revision 1.2  84/04/02  14:22:49  donn
2243202Sbostic  * Bug in copy propagation missed places where temporaries are assigned to
2343202Sbostic  * by OPSTAREQ or OPPLUSEQ, e.g. exponentiation with an integer constant
2443202Sbostic  * power, expanded inline.
2543202Sbostic  *
2643202Sbostic  */
2743202Sbostic 
2843202Sbostic #include "defs.h"
2943202Sbostic #include "optim.h"
3043202Sbostic 
3143202Sbostic /*
3243202Sbostic  *  This file contains code for determination of basic blocks,
3343202Sbostic  *  as well as some other optimization supporting routines
3443202Sbostic  *  [including the main routine 'optimize()'].
3543202Sbostic  *
3643202Sbostic  *  The compiler's general debugging flag ['debugflag'] has been
3743202Sbostic  *  extended to provide the capability of having multiple flags
3843202Sbostic  *  which are contained in an array.  If the option -d is used,
3943202Sbostic  *  then the flag debugflag[0] is set.  If a sequence of one or more
4043202Sbostic  *  numbers are given (e.g, -d3,7,12), then the flags debugflag[3],
4143202Sbostic  *  debugflag[7], and debugflag[12] are set.  The maximum number of
4243202Sbostic  *  flags available is specified in the defines.h file.
4343202Sbostic  */
4443202Sbostic 
4543202Sbostic 
4643202Sbostic Bblockp	firstblock = NULL;		/* first block in buffer */
4743202Sbostic Bblockp	lastblock = NULL;		/* last block in buffer */
4843202Sbostic 
4943202Sbostic expptr	tempalloc();
5043202Sbostic 
5143202Sbostic 
5243202Sbostic optimize ()
5343202Sbostic 
5443202Sbostic {
5543202Sbostic Bblockp bb;
5643202Sbostic Slotp	sl,nextsl;
5743202Sbostic 
5843202Sbostic if (debugflag[2]) showbuffer ();
5943202Sbostic 
6043202Sbostic optloops ();
6143202Sbostic 
6243202Sbostic if (debugflag[3]) showbuffer ();
6343202Sbostic 
6443202Sbostic formbblock ();
6543202Sbostic optcse ();
6643202Sbostic 
6743202Sbostic if (debugflag[4]) showbuffer ();
6843202Sbostic 
6943202Sbostic if (! debugflag[7])
7043202Sbostic 	copyprop ();
7143202Sbostic 
7243202Sbostic if (debugflag[9]) showbuffer ();
7343202Sbostic 
7443202Sbostic for (sl = firstslot; sl; sl = nextsl)
7543202Sbostic 	{
7643202Sbostic 	nextsl = sl->next;
7743202Sbostic 	if (sl->type == SKFRTEMP)
7843202Sbostic 		{
7943202Sbostic 		templist = mkchain (sl->expr,templist);
8043202Sbostic 		sl->expr = NULL;
8143202Sbostic 		delslot (sl);
8243202Sbostic 		}
8343202Sbostic 	else
8443202Sbostic 		sl->expr = tempalloc (sl->expr);
8543202Sbostic 	}
8643202Sbostic 
8743202Sbostic if (! debugflag[10])
8843202Sbostic 	regalloc ();
8943202Sbostic 
9043202Sbostic flushopt ();
9143202Sbostic }
9243202Sbostic 
9343202Sbostic 
9443202Sbostic 
9543202Sbostic /*
9643202Sbostic  *  creates a new basic block record
9743202Sbostic  */
9843202Sbostic 
9943202Sbostic LOCAL Bblockp newblock (sl)
10043202Sbostic Slotp	sl;
10143202Sbostic 
10243202Sbostic {
10343202Sbostic register Bblockp bb;
10443202Sbostic 
10543202Sbostic bb = ALLOC( bblock );
10643202Sbostic bb->next = NULL ;
10743202Sbostic if (lastblock)
10843202Sbostic 	{
10943202Sbostic 	bb->prev = lastblock;
11043202Sbostic 	lastblock->next = bb;
11143202Sbostic 	lastblock = bb;
11243202Sbostic 	}
11343202Sbostic else
11443202Sbostic 	{
11543202Sbostic 	firstblock = lastblock = bb;
11643202Sbostic 	bb->prev = NULL;
11743202Sbostic 	}
11843202Sbostic 
11943202Sbostic bb->first = sl;
12043202Sbostic return (bb);
12143202Sbostic }
12243202Sbostic 
12343202Sbostic 
12443202Sbostic 
12543202Sbostic /*
12643202Sbostic  *  scans slot buffer, creating basic block records
12743202Sbostic  */
12843202Sbostic 
12943202Sbostic formbblock ()
13043202Sbostic 
13143202Sbostic {
13243202Sbostic Slotp	sl;
13343202Sbostic field	type;
13443202Sbostic Bblockp	newbb;
13543202Sbostic 
13643202Sbostic newbb = NULL;
13743202Sbostic for (sl = firstslot; sl; sl = sl->next)
13843202Sbostic 	{
13943202Sbostic 	type = sl->type;
14043202Sbostic 	switch (type)
14143202Sbostic 		{
14243202Sbostic 		case SKEQ:
14343202Sbostic 			if (!newbb)
14443202Sbostic 				newbb = newblock(sl);
14543202Sbostic 			if (containscall(sl->expr))
14643202Sbostic 				{
14743202Sbostic 				newbb->last = sl;
14843202Sbostic 				newbb = NULL;
14943202Sbostic 				}
15043202Sbostic 			break;
15143202Sbostic 		case SKNULL:
15243202Sbostic 		case SKASSIGN:
15343202Sbostic 		case SKFRTEMP:
15443202Sbostic 			if (!newbb)
15543202Sbostic 				newbb = newblock(sl);
15643202Sbostic 			break;
15743202Sbostic 		case SKPAUSE:
15843202Sbostic 		case SKSTOP:
15943202Sbostic 		case SKIFN:
16043202Sbostic 		case SKGOTO:
16143202Sbostic 		case SKCMGOTO:
16243202Sbostic 		case SKARIF:
16343202Sbostic 		case SKASGOTO:
16443202Sbostic 		case SKIOIFN:
16543202Sbostic 		case SKCALL:
16643202Sbostic 		case SKRETURN:
16743202Sbostic 			if (!newbb)
16843202Sbostic 				newbb = newblock(sl);
16943202Sbostic 			newbb->last = sl;
17043202Sbostic 			newbb = NULL;
17143202Sbostic 			break;
17243202Sbostic 		case SKLABEL:
17343202Sbostic 			if (newbb)
17443202Sbostic 				newbb->last = sl->prev;
17543202Sbostic 			newbb = newblock(sl);
17643202Sbostic 			break;
17743202Sbostic 		case SKDOHEAD:
17843202Sbostic 		case SKENDDO:
17943202Sbostic 			if (!newbb)
18043202Sbostic 				newbb = newblock(sl);
18143202Sbostic 			break;
18243202Sbostic 		default:
18343202Sbostic 			badthing("SKtype", "formbblock", type);
18443202Sbostic 			break;
18543202Sbostic 		}
18643202Sbostic 	}
18743202Sbostic if (newbb)
18843202Sbostic 	newbb->last = lastslot;
18943202Sbostic }
19043202Sbostic 
19143202Sbostic 
19243202Sbostic 
19343202Sbostic /*
19443202Sbostic  *  frees all basic block records
19543202Sbostic  *  as well as the id and value node chains hanging off the bb and their
19643202Sbostic  *  respective cross link chains (IDlist, DUPlist and NODElist structs)
19743202Sbostic  */
19843202Sbostic 
19943202Sbostic clearbb ()
20043202Sbostic {
20143202Sbostic Bblockp	bb,next;
20243202Sbostic 
20343202Sbostic for (bb = firstblock; bb; bb = next)
20443202Sbostic 	{
20543202Sbostic 	next = bb->next;
20643202Sbostic 	   {
20743202Sbostic 	     idptr idp,next;
20843202Sbostic 	     for(idp = bb->headid; idp; idp = next)
20943202Sbostic 		{
21043202Sbostic 		 next = idp->next;
21143202Sbostic 		      {
21243202Sbostic 		      nodelptr nodelp, next;
21343202Sbostic 	              for(nodelp = idp->headnodelist; nodelp; nodelp = next)
21443202Sbostic 			 {
21543202Sbostic 			    next = nodelp->next;
21643202Sbostic 		            free( (charptr) nodelp);
21743202Sbostic 		         }
21843202Sbostic 		      }
21943202Sbostic                  free( (charptr) idp);
22043202Sbostic 	        }
22143202Sbostic            }
22243202Sbostic 	   {
22343202Sbostic 	     valuen vp,next;
22443202Sbostic 	     for(vp = bb->headnode; vp; vp = next)
22543202Sbostic 		{
22643202Sbostic 		 next = vp->next;
22743202Sbostic 		      {
22843202Sbostic 		      idlptr idlp, next;
22943202Sbostic 	              for(idlp = vp->headdeplist; idlp; idlp = next)
23043202Sbostic 			 {
23143202Sbostic 			    next = idlp->next;
23243202Sbostic 		            free( (charptr) idlp);
23343202Sbostic 		         }
23443202Sbostic 		      }
23543202Sbostic 		      {
23643202Sbostic 		      duplptr duplp, next;
23743202Sbostic 	              for(duplp = vp->headduplist; duplp; duplp = next)
23843202Sbostic 			 {
23943202Sbostic 			    next = duplp->next;
24043202Sbostic 		            free( (charptr) duplp);
24143202Sbostic 		         }
24243202Sbostic 		      }
24343202Sbostic                  free( (charptr) vp);
24443202Sbostic 	        }
24543202Sbostic            }
24643202Sbostic 	free ( (charptr) bb);
24743202Sbostic 	}
24843202Sbostic firstblock = lastblock = NULL;
24943202Sbostic }
25043202Sbostic 
25143202Sbostic 
25243202Sbostic /* structure for maintaining records on copy statements */
25343202Sbostic 
25443202Sbostic typedef struct Subrec {
25543202Sbostic 	Addrp	lmem;
25643202Sbostic 	Addrp	rmem;
25743202Sbostic 	int	sets;
25843202Sbostic } *Subrecp;
25943202Sbostic 
26043202Sbostic 
26143202Sbostic LOCAL chainp sublist;	/* list of copy statements */
26243202Sbostic LOCAL int prop1count;	/* count of number of temporaries eliminated */
26343202Sbostic LOCAL int prop2count;	/* count of number of uses of temporaries replaced */
26443202Sbostic 
26543202Sbostic expptr rmcommaop();
26643202Sbostic Addrp subfor();
26743202Sbostic 
26843202Sbostic 
26943202Sbostic 
27043202Sbostic /*
27143202Sbostic  *  eliminates copy statements of the form T1 = T2 from the intermediate
27243202Sbostic  *  code, where T1 and T2 are temporary variables which are each
27343202Sbostic  *  set only once;  eliminates the copy statement and replaces each
27443202Sbostic  *  use of T1 by T2 (T1 is therefore totally eliminated).
27543202Sbostic  */
27643202Sbostic 
27743202Sbostic LOCAL copyprop ()
27843202Sbostic 
27943202Sbostic {
28043202Sbostic Slotp	sl,nextsl;
28143202Sbostic expptr	expr;
28243202Sbostic Tempp	lp,rp;
28343202Sbostic 
28443202Sbostic for (sl = firstslot; sl; sl = sl->next)
28543202Sbostic 	sl->expr = rmcommaop (sl->expr,sl);
28643202Sbostic 
28743202Sbostic prop1count = prop2count = 0;
28843202Sbostic findcopies ();
28943202Sbostic 
29043202Sbostic for (sl = firstslot; sl; sl = nextsl)
29143202Sbostic 	{
29243202Sbostic 	nextsl = sl->next;
29343202Sbostic 	expr = sl->expr;
29443202Sbostic 
29543202Sbostic 	if ((sl->type == SKFRTEMP) && subfor (expr))
29643202Sbostic 		{
29743202Sbostic 		delslot (sl);
29843202Sbostic 		expr = ENULL;
29943202Sbostic 		}
30043202Sbostic 	else if (expr && expr->tag == TEXPR &&
30143202Sbostic 			expr->exprblock.opcode == OPASSIGN)
30243202Sbostic 		{
30343202Sbostic 		lp = (Tempp) expr->exprblock.leftp;
30443202Sbostic 		rp = (Tempp) expr->exprblock.rightp;
30543202Sbostic 		if (lp->tag == TTEMP && rp->tag == TTEMP)
30643202Sbostic 			if (subfor(lp->memalloc) == rp->memalloc
30743202Sbostic 					&& !subfor (rp->memalloc))
30843202Sbostic 				{
30943202Sbostic 				frexpr (expr);
31043202Sbostic 				expr = sl->expr = ENULL;
31143202Sbostic 				prop1count++;
31243202Sbostic 				}
31343202Sbostic 		}
31443202Sbostic 
31543202Sbostic 	propagate (expr);
31643202Sbostic 	}
31743202Sbostic 
31843202Sbostic if (debugflag[0])
31943202Sbostic 	fprintf (diagfile,
32043202Sbostic 	    "%d temporarie%s replaced by copy propagation (%d use%s)\n",
32143202Sbostic 		prop1count,(prop1count==1 ? "" : "s"),
32243202Sbostic 		prop2count,(prop2count==1 ? "" : "s") );
32343202Sbostic }
32443202Sbostic 
32543202Sbostic 
32643202Sbostic 
32743202Sbostic /*
32843202Sbostic  *  finds copy statements and enters information in table
32943202Sbostic  */
33043202Sbostic 
33143202Sbostic LOCAL findcopies ()
33243202Sbostic 
33343202Sbostic {
33443202Sbostic Slotp	sl;
33543202Sbostic expptr	expr;
33643202Sbostic chainp	cp;
33743202Sbostic 
33843202Sbostic for (sl = firstslot; sl; sl = sl->next)
33943202Sbostic 	{
34043202Sbostic 	expr = sl->expr;
34143202Sbostic 	if (expr) switch (expr->tag)
34243202Sbostic 	    {
34343202Sbostic 	    case TEXPR:
34443202Sbostic 		ckexpr (expr);
34543202Sbostic 		break;
34643202Sbostic 
34743202Sbostic 	    case TLIST:
34843202Sbostic 		for (cp = expr->listblock.listp; cp; cp = cp->nextp)
34943202Sbostic 			{
35043202Sbostic 			expr = (expptr) cp->datap;
35143202Sbostic 			ckexpr (expr);
35243202Sbostic 			}
35343202Sbostic 		break;
35443202Sbostic 
35543202Sbostic 	    default:
35643202Sbostic 		break;
35743202Sbostic 	    }
35843202Sbostic 	}
35943202Sbostic }
36043202Sbostic 
36143202Sbostic 
36243202Sbostic 
36343202Sbostic /*
36443202Sbostic  *  checks an individual expression
36543202Sbostic  */
36643202Sbostic 
36743202Sbostic ckexpr (expr)
36843202Sbostic expptr	expr;
36943202Sbostic 
37043202Sbostic {
37143202Sbostic Tempp	lp,rp;
37243202Sbostic int	oc = expr->exprblock.opcode;
37343202Sbostic 
37443202Sbostic if (oc == OPASSIGN || oc == OPPLUSEQ || oc == OPSTAREQ)
37543202Sbostic 	{
37643202Sbostic 	lp = (Tempp) expr->exprblock.leftp;
37743202Sbostic 	rp = (Tempp) expr->exprblock.rightp;
37843202Sbostic 	if (lp->tag == TTEMP)
37943202Sbostic 		if (rp->tag == TTEMP && oc == OPASSIGN)
38043202Sbostic 			enter (lp->memalloc, rp->memalloc);
38143202Sbostic 		else
38243202Sbostic 			enter (lp->memalloc, ENULL);
38343202Sbostic 	}
38443202Sbostic }
38543202Sbostic 
38643202Sbostic 
38743202Sbostic 
38843202Sbostic /*
38943202Sbostic  *  Enters the given memalloc values in the table (or update if they
39043202Sbostic  *  are already there), for the assignment statement m1 = m2.
39143202Sbostic  *  If m2 is NULL, this indicates that the assignment is not a copy
39243202Sbostic  *  statement.
39343202Sbostic  */
39443202Sbostic 
39543202Sbostic LOCAL enter (m1,m2)
39643202Sbostic Addrp	m1,m2;
39743202Sbostic 
39843202Sbostic {
39943202Sbostic chainp	cp;
40043202Sbostic Subrecp old,new;
40143202Sbostic 
40243202Sbostic for (cp = sublist; cp; cp = cp->nextp)
40343202Sbostic 	{
40443202Sbostic 	old = (Subrecp) cp->datap;
40543202Sbostic 	if (old->lmem == m1)
40643202Sbostic 		{
40743202Sbostic 		old->sets++;
40843202Sbostic 		return;
40943202Sbostic 		}
41043202Sbostic 	}
41143202Sbostic 
41243202Sbostic new = ALLOC (Subrec);
41343202Sbostic new->lmem = m1;
41443202Sbostic new->rmem = m2;
41543202Sbostic new->sets = 1;
41643202Sbostic sublist = mkchain (new, sublist);
41743202Sbostic }
41843202Sbostic 
41943202Sbostic 
42043202Sbostic 
42143202Sbostic /*
42243202Sbostic  *  looks for record for the given memalloc value
42343202Sbostic  */
42443202Sbostic 
42543202Sbostic LOCAL Subrecp lookup (mem)
42643202Sbostic Addrp	mem;
42743202Sbostic 
42843202Sbostic {
42943202Sbostic chainp	cp;
43043202Sbostic Subrecp rec;
43143202Sbostic 
43243202Sbostic for (cp = sublist; cp; cp = cp->nextp)
43343202Sbostic 	{
43443202Sbostic 	rec = (Subrecp) cp->datap;
43543202Sbostic 	if (rec->lmem == mem)
43643202Sbostic 		return rec;
43743202Sbostic 	}
43843202Sbostic 
43943202Sbostic return NULL;
44043202Sbostic }
44143202Sbostic 
44243202Sbostic 
44343202Sbostic 
44443202Sbostic /*
44543202Sbostic  *  checks to see if there is a substitute for given memalloc value
44643202Sbostic  */
44743202Sbostic 
44843202Sbostic LOCAL Addrp subfor (mem)
44943202Sbostic Addrp	mem;
45043202Sbostic 
45143202Sbostic {
45243202Sbostic Subrecp rec,rec2;
45343202Sbostic Addrp	sub;
45443202Sbostic 
45543202Sbostic rec = lookup (mem);
45643202Sbostic if (rec && rec->sets == 1)
45743202Sbostic 	{
45843202Sbostic 	sub = rec->rmem;
45943202Sbostic 	rec2 = lookup(sub);
46043202Sbostic 	if (rec2 && rec2->sets == 1)
46143202Sbostic 		return sub;
46243202Sbostic 	}
46343202Sbostic 
46443202Sbostic return NULL;
46543202Sbostic }
46643202Sbostic 
46743202Sbostic 
46843202Sbostic 
46943202Sbostic /*
47043202Sbostic  *  actually propagates the information
47143202Sbostic  */
47243202Sbostic 
47343202Sbostic LOCAL propagate (expr)
47443202Sbostic expptr	expr;
47543202Sbostic 
47643202Sbostic {
47743202Sbostic chainp	t;
47843202Sbostic Addrp	new;
47943202Sbostic 
48043202Sbostic if (! expr) return;
48143202Sbostic 
48243202Sbostic switch (expr->tag)
48343202Sbostic 	{
48443202Sbostic 	case TEXPR:
48543202Sbostic 		propagate (expr->exprblock.leftp);
48643202Sbostic 		propagate (expr->exprblock.rightp);
48743202Sbostic 		break;
48843202Sbostic 
48943202Sbostic 	case TADDR:
49043202Sbostic 		propagate (expr->addrblock.vleng);
49143202Sbostic 		propagate (expr->addrblock.memoffset);
49243202Sbostic 		break;
49343202Sbostic 
49443202Sbostic 	case TLIST:
49543202Sbostic 		for (t = expr->listblock.listp; t; t = t->nextp)
49643202Sbostic 			propagate (t->datap);
49743202Sbostic 		break;
49843202Sbostic 
49943202Sbostic 	case TTEMP:
50043202Sbostic 		new = subfor (expr->tempblock.memalloc);
50143202Sbostic 		if (new)
50243202Sbostic 			{
50343202Sbostic 			expr->tempblock.memalloc = new;
50443202Sbostic 			prop2count++;
50543202Sbostic 			}
50643202Sbostic 		break;
50743202Sbostic 
50843202Sbostic 	default:
50943202Sbostic 		break;
51043202Sbostic 	}
51143202Sbostic }
51243202Sbostic 
51343202Sbostic 
51443202Sbostic 
51543202Sbostic /*
51643202Sbostic  *  allocates ADDR blocks for each TEMP in the expression
51743202Sbostic  */
51843202Sbostic 
51943202Sbostic LOCAL expptr tempalloc (expr)
52043202Sbostic expptr	expr;
52143202Sbostic 
52243202Sbostic {
52343202Sbostic chainp	t;
52443202Sbostic 
52543202Sbostic if (! expr)
52643202Sbostic 	return NULL;
52743202Sbostic 
52843202Sbostic switch (expr->tag)
52943202Sbostic     {
53043202Sbostic     case TEXPR:
53143202Sbostic 	expr->exprblock.leftp = tempalloc (expr->exprblock.leftp);
53243202Sbostic 	expr->exprblock.rightp = tempalloc (expr->exprblock.rightp);
53343202Sbostic 	break;
53443202Sbostic 
53543202Sbostic     case TADDR:
53643202Sbostic 	expr->addrblock.vleng = tempalloc (expr->addrblock.vleng);
53743202Sbostic 	expr->addrblock.memoffset = tempalloc (expr->addrblock.memoffset);
53843202Sbostic 	break;
53943202Sbostic 
54043202Sbostic     case TLIST:
54143202Sbostic 	for (t = expr->listblock.listp; t; t = t->nextp)
54243202Sbostic 		t->datap = (tagptr) tempalloc (t->datap);
54343202Sbostic 	break;
54443202Sbostic 
54543202Sbostic     case TTEMP:
54643202Sbostic 	return (expptr) cpexpr (altmpn (expr));
54743202Sbostic 	break;
54843202Sbostic 
54943202Sbostic     default:
55043202Sbostic 	break;
55143202Sbostic     }
55243202Sbostic return expr;
55343202Sbostic }
55443202Sbostic 
55543202Sbostic 
55643202Sbostic /********************* debugging routines *********************/
55743202Sbostic 
55843202Sbostic 
55943202Sbostic 
56043202Sbostic Announce (s,q)
56143202Sbostic char *s;
56243202Sbostic expptr q;
56343202Sbostic 
56443202Sbostic {
56543202Sbostic fprintf (diagfile,"\nAn expression [%s]----->\n",s);
56643202Sbostic showexpr(q,0);
56743202Sbostic fprintf (diagfile,"\n-------------end of expr--------------\n");
56843202Sbostic }
56943202Sbostic 
57043202Sbostic 
57143202Sbostic 
57243202Sbostic /*
57343202Sbostic  *  dump the basic block buffer, including expressions, mnemonically
57443202Sbostic  */
57543202Sbostic 
57643202Sbostic showbuffer ()
57743202Sbostic 
57843202Sbostic {
57943202Sbostic Slotp	sl;
58043202Sbostic Bblockp	bb;
58143202Sbostic int	i;
58243202Sbostic 
58343202Sbostic fprintf (diagfile,"Basic blocks with first and last slots ----------\n");
58443202Sbostic for (i=1, bb = firstblock; bb; i++, bb = bb->next)
58543202Sbostic 	fprintf (diagfile,"%2d.  %d  %d\n",i,bb->first,bb->last);
58643202Sbostic fprintf (diagfile,"\n");
58743202Sbostic 
58843202Sbostic fprintf (diagfile,"Slots and expressions ----------\n");
58943202Sbostic 
59043202Sbostic fprintf (diagfile,"tag pointer vtype vclass vstg vleng\n");
59143202Sbostic fprintf (diagfile,"          ADDR memno memoffset istemp ntempelt varleng\n");
59243202Sbostic fprintf (diagfile,"          TEMP memalloc istemp ntempelt varleng\n");
59343202Sbostic fprintf (diagfile,"          EXPR opcode leftp rightp\n");
59443202Sbostic fprintf (diagfile,"          LIST type listp\n");
59543202Sbostic fprintf (diagfile,"\n");
59643202Sbostic 
59743202Sbostic for (i=1, sl = firstslot; sl; i++, sl = sl->next)
59843202Sbostic 	{
59943202Sbostic 	fprintf (diagfile,"%2d.  ",i);
60043202Sbostic 	showslt (sl);
60143202Sbostic 	}
60243202Sbostic fprintf (diagfile,"---------- End of showbuffer ----------\n");
60343202Sbostic }
60443202Sbostic 
60543202Sbostic 
60643202Sbostic 
60743202Sbostic /*
60843202Sbostic  *  dumps a single slot in the code buffer
60943202Sbostic  */
61043202Sbostic 
61143202Sbostic LOCAL charptr Zslot[] = {"NULL",
61243202Sbostic 	"IFN","GOTO","LABEL","EQ","CALL","CMGOTO","STOP","DOHEAD",
61343202Sbostic 	"ENDDO","ARIF","RETURN","ASGOTO","PAUSE","ASSIGN","IOIFN","FRTEMP"};
61443202Sbostic 
61543202Sbostic 
61643202Sbostic 
61743202Sbostic showslt (sl)
61843202Sbostic Slotp sl;
61943202Sbostic 
62043202Sbostic {
62143202Sbostic fprintf (diagfile,"(%2d)  %d  %s  %d\n",
62243202Sbostic 	sl->lineno,sl,Zslot[sl->type],sl->label);
62343202Sbostic showexpr (sl->expr,0);
62443202Sbostic fprintf (diagfile,"\n");
62543202Sbostic }
62643202Sbostic 
62743202Sbostic 
62843202Sbostic 
62943202Sbostic showslottype (type)
63043202Sbostic int type;
63143202Sbostic 
63243202Sbostic {
63343202Sbostic fprintf (diagfile,"%s\n",Zslot[type]);
63443202Sbostic }
63543202Sbostic 
63643202Sbostic 
63743202Sbostic 
63843202Sbostic /*
63943202Sbostic  *  displays the given expression at the given indentation, showing
64043202Sbostic  *  its subexpressions at further indentations
64143202Sbostic  */
64243202Sbostic 
64343202Sbostic LOCAL charptr Ztag[] = {"----",
64443202Sbostic 	"NAME","CONST","EXPR","ADDR","TEMP","PRIM","LIST","IMPLDO","ERROR"};
64543202Sbostic LOCAL charptr Zstg[] = {"unk",
64643202Sbostic 	"ARG","AUTO","BSS","INIT","CONST","EXT","INTR","STFUNCT",
64743202Sbostic 	"COMMON","EQUIV","REG","LENG","NULL","PREG"};
64843202Sbostic LOCAL charptr Zclass[] = {"unk",
64943202Sbostic 	"PARAM","VAR","ENTRY","MAIN","BLOCK","PROC","NAMELIST"};
65043202Sbostic LOCAL charptr Zop[] = {"----",
65143202Sbostic 	"PLUS","MINUS","STAR","SLASH","POWER","NEG","OR","AND","EQV",
65243202Sbostic 	"NEQV","NOT","CONCAT","LT","EQ","GT","LE","NE","GE","CALL",
65343202Sbostic 	"CCALL","ASSIGN","PLUSEQ","STAREQ","CONV","LSHIFT","MOD",
65443202Sbostic 	"COMMA","QUEST","COLON","ABS","MIN","MAX","ADDR","INDIRECT",
65543202Sbostic 	"BITOR","BITAND","BITXOR","BITNOT","RSHIFT","PAREN"};
65643202Sbostic LOCAL charptr Ztype[] = {"unk",
65743202Sbostic 	"ADDR","SHORT","LONG","REAL","DREAL","COMPLEX","DCOMPLEX",
65843202Sbostic 	"LOGICAL","CHAR","SUBR","ERROR"};
65943202Sbostic 
66043202Sbostic 
66143202Sbostic showexpr(p,indent)
66243202Sbostic tagptr p;
66343202Sbostic int indent;
66443202Sbostic 
66543202Sbostic {
66643202Sbostic int i;
66743202Sbostic int type;
66843202Sbostic chainp q;
66943202Sbostic 
67043202Sbostic #define PRHEAD(q) fprintf(diagfile,"%s %d %s %s %s %d", \
67143202Sbostic 	Ztag[q->tag], q, Ztype[q->headblock.vtype], \
67243202Sbostic 	Zclass[q->headblock.vclass], Zstg[q->headblock.vstg], \
67343202Sbostic 	q->headblock.vleng);
67443202Sbostic #define SHOWEXPR(p) showexpr(p,indent+2)
67543202Sbostic 
67643202Sbostic 
67743202Sbostic 
67843202Sbostic if(p == NULL)
67943202Sbostic 	return;
68043202Sbostic 
68143202Sbostic for (i=0; i<indent; i++)
68243202Sbostic 	putc(' ',diagfile);
68343202Sbostic 
68443202Sbostic switch(p->tag)
68543202Sbostic          {
68643202Sbostic          case TCONST:
68743202Sbostic               PRHEAD(p);
68843202Sbostic 
68943202Sbostic               type=p->constblock.vtype;
69043202Sbostic               if (ISCHAR(p))
69143202Sbostic                  {
69243202Sbostic                       fprintf(diagfile," ISCHAR ccp= %d\n",
693*46301Sbostic                                                    p->constblock.constant.ccp);
69443202Sbostic                       SHOWEXPR(p->constblock.vleng);
69543202Sbostic                  }
69643202Sbostic               else  if( ISINT(type) )
697*46301Sbostic                    fprintf(diagfile," ci= %d\n",p->constblock.constant.ci);
69843202Sbostic               else if( ISREAL(type) )
699*46301Sbostic                    fprintf(diagfile,
700*46301Sbostic 			" cd[0]= %e\n",p->constblock.constant.cd[0]);
70143202Sbostic               else fprintf(diagfile," cd[0]= %e  cd[1]= %e\n",
702*46301Sbostic                             p->constblock.constant.cd[0],
703*46301Sbostic                             p->constblock.constant.cd[1] );
70443202Sbostic               break;
70543202Sbostic 
70643202Sbostic          case TADDR:
70743202Sbostic               PRHEAD(p);
70843202Sbostic               fprintf(diagfile,
70943202Sbostic               " memno= %d %d %d %d %d\n",
71043202Sbostic               p->addrblock.memno,p->addrblock.memoffset,p->addrblock.istemp,
71143202Sbostic               p->addrblock.ntempelt,p->addrblock.varleng);
71243202Sbostic               SHOWEXPR(p->addrblock.vleng);
71343202Sbostic               SHOWEXPR(p->addrblock.memoffset);
71443202Sbostic               break;
71543202Sbostic 
71643202Sbostic          case TTEMP:
71743202Sbostic 	      fprintf(diagfile,"%s %d %s %s %d",
71843202Sbostic 			Ztag[p->tag], p, Ztype[p->headblock.vtype],
71943202Sbostic 			Zclass[p->headblock.vclass],
72043202Sbostic 			p->headblock.vleng);
72143202Sbostic               fprintf(diagfile,
72243202Sbostic 		" memalloc= %d %d %d %d\n",
72343202Sbostic 		p->tempblock.memalloc,p->tempblock.istemp,
72443202Sbostic 		p->tempblock.ntempelt,p->tempblock.varleng);
72543202Sbostic               SHOWEXPR(p->tempblock.vleng);
72643202Sbostic 	      SHOWEXPR(p->tempblock.memalloc);
72743202Sbostic               break;
72843202Sbostic 
72943202Sbostic          case TERROR:
73043202Sbostic               fprintf(diagfile,"ERROR %d\n",p);
73143202Sbostic               break;
73243202Sbostic 
73343202Sbostic          case TNAME:
73443202Sbostic               fprintf(diagfile,"NAME %d\n",p);
73543202Sbostic               return;
73643202Sbostic 
73743202Sbostic          case TPRIM:
73843202Sbostic               fprintf(diagfile,"PRIM %d --- not implemented\n",p);
73943202Sbostic               break;
74043202Sbostic 
74143202Sbostic          case TEXPR:
74243202Sbostic               PRHEAD(p);
74343202Sbostic               fprintf(diagfile," opcode= %s %d %d\n",
74443202Sbostic                      Zop[p->exprblock.opcode],p->exprblock.leftp,
74543202Sbostic                      p->exprblock.rightp);
74643202Sbostic               SHOWEXPR(p->exprblock.leftp);
74743202Sbostic               if(p->exprblock.rightp)
74843202Sbostic                     SHOWEXPR(p->exprblock.rightp);
74943202Sbostic               break;
75043202Sbostic 
75143202Sbostic          case TLIST:
75243202Sbostic               fprintf(diagfile,"LIST %d %s %d\n",p,
75343202Sbostic                       Ztype[p->listblock.vtype],p->listblock.listp);
75443202Sbostic               for(q= p->listblock.listp ; q ; q = q->nextp)
75543202Sbostic                       SHOWEXPR(q->datap);
75643202Sbostic 	      for (i=0; i<indent; i++)
75743202Sbostic 		putc (' ',diagfile);
75843202Sbostic               fprintf(diagfile,"END LIST %d\n",p);
75943202Sbostic               break;
76043202Sbostic 
76143202Sbostic          default:
76243202Sbostic               fprintf(diagfile,"showexpr BAD TAG= %d at %d \n",p->tag,p);
76343202Sbostic            }
76443202Sbostic }
76543202Sbostic 
76643202Sbostic 
76743202Sbostic 
76843202Sbostic selective()/************************************/
76943202Sbostic {
77043202Sbostic int i;
77143202Sbostic Slotp sl;
77243202Sbostic 
77343202Sbostic i=0;
77443202Sbostic fprintf (stderr,"SELECTIVE OUTPUT\n");
77543202Sbostic for (sl=firstslot;sl;sl=sl->next)
77643202Sbostic 	{
77743202Sbostic 	i++;
77843202Sbostic /*
77943202Sbostic 	if (i>=176 && i<184)
78043202Sbostic */
78143202Sbostic 		{
78243202Sbostic 		fprintf (stderr,"%d.  ",i);
78343202Sbostic 		showslt(sl);
78443202Sbostic 		}
78543202Sbostic 	}
78643202Sbostic }
78743202Sbostic 
78843202Sbostic 
78943202Sbostic 
79043202Sbostic 
79143202Sbostic LOCAL containscall(p)
79243202Sbostic expptr p;
79343202Sbostic {
79443202Sbostic   chainp cp;
79543202Sbostic 
79643202Sbostic   if (p == NULL)
79743202Sbostic     return NO;
79843202Sbostic 
79943202Sbostic   switch (p->tag)
80043202Sbostic     {
80143202Sbostic     case TADDR:
80243202Sbostic       if (containscall(p->addrblock.vleng)
80343202Sbostic 	  || containscall(p->addrblock.memoffset))
80443202Sbostic 	return YES;
80543202Sbostic       else
80643202Sbostic         return NO;
80743202Sbostic 
80843202Sbostic     case TCONST:
80943202Sbostic       return NO;
81043202Sbostic 
81143202Sbostic     case TERROR:
81243202Sbostic       return NO;
81343202Sbostic 
81443202Sbostic     case TEXPR:
81543202Sbostic       if (p->exprblock.opcode == OPCALL ||
81643202Sbostic 	  p->exprblock.opcode == OPCCALL)
81743202Sbostic 	return YES;
81843202Sbostic       if (containscall(p->exprblock.vleng) ||
81943202Sbostic 	  containscall(p->exprblock.leftp) ||
82043202Sbostic 	  containscall(p->exprblock.rightp))
82143202Sbostic 	return YES;
82243202Sbostic       else
82343202Sbostic 	return NO;
82443202Sbostic 
82543202Sbostic     case TLIST:
82643202Sbostic       cp = p->listblock.listp;
82743202Sbostic       while (cp)
82843202Sbostic 	{
82943202Sbostic 	  if (containscall(cp->datap))
83043202Sbostic 	    return YES;
83143202Sbostic 	  cp = cp->nextp;
83243202Sbostic 	}
83343202Sbostic       return NO;
83443202Sbostic 
83543202Sbostic     default:
83643202Sbostic       return YES;
83743202Sbostic     }
83843202Sbostic }
839