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