xref: /csrg-svn/usr.bin/f77/pass1.vax/bb.c (revision 47955)
1*47955Sbostic /*-
2*47955Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47955Sbostic  * All rights reserved.
4*47955Sbostic  *
5*47955Sbostic  * %sccs.include.proprietary.c%
622798Smckusick  */
722798Smckusick 
822798Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)bb.c	5.4 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122798Smckusick 
1222798Smckusick /*
1322798Smckusick  * bb.c
1422798Smckusick  *
1522798Smckusick  * Basic block optimizations.
1622798Smckusick  *
1722798Smckusick  * University of Utah CS Dept modification history:
1822798Smckusick  *
1926510Sdonn  * $Log:	bb.c,v $
2026510Sdonn  * Revision 5.2  86/03/09  18:13:56  donn
2126510Sdonn  * In tempalloc(), don't forget to treat the vleng tree of a temp block
2226510Sdonn  * before allocating it with altmpn.
2326510Sdonn  *
2422798Smckusick  * Revision 2.1  84/07/19  12:01:20  donn
2522798Smckusick  * Changed comment headers for UofU.
2622798Smckusick  *
2722798Smckusick  * Revision 1.2  84/04/02  14:22:49  donn
2822798Smckusick  * Bug in copy propagation missed places where temporaries are assigned to
2922798Smckusick  * by OPSTAREQ or OPPLUSEQ, e.g. exponentiation with an integer constant
3022798Smckusick  * power, expanded inline.
3122798Smckusick  *
3222798Smckusick  */
3322798Smckusick 
3422798Smckusick #include "defs.h"
3522798Smckusick #include "optim.h"
3622798Smckusick 
3722798Smckusick /*
3822798Smckusick  *  This file contains code for determination of basic blocks,
3922798Smckusick  *  as well as some other optimization supporting routines
4022798Smckusick  *  [including the main routine 'optimize()'].
4122798Smckusick  *
4222798Smckusick  *  The compiler's general debugging flag ['debugflag'] has been
4322798Smckusick  *  extended to provide the capability of having multiple flags
4422798Smckusick  *  which are contained in an array.  If the option -d is used,
4522798Smckusick  *  then the flag debugflag[0] is set.  If a sequence of one or more
4622798Smckusick  *  numbers are given (e.g, -d3,7,12), then the flags debugflag[3],
4722798Smckusick  *  debugflag[7], and debugflag[12] are set.  The maximum number of
4822798Smckusick  *  flags available is specified in the defines.h file.
4922798Smckusick  */
5022798Smckusick 
5122798Smckusick 
5222798Smckusick Bblockp	firstblock = NULL;		/* first block in buffer */
5322798Smckusick Bblockp	lastblock = NULL;		/* last block in buffer */
5422798Smckusick 
5522798Smckusick expptr	tempalloc();
5622798Smckusick 
5722798Smckusick 
optimize()5822798Smckusick optimize ()
5922798Smckusick 
6022798Smckusick {
6122798Smckusick Bblockp bb;
6222798Smckusick Slotp	sl,nextsl;
6322798Smckusick 
6422798Smckusick if (debugflag[2]) showbuffer ();
6522798Smckusick 
6622798Smckusick optloops ();
6722798Smckusick 
6822798Smckusick if (debugflag[3]) showbuffer ();
6922798Smckusick 
7022798Smckusick formbblock ();
7122798Smckusick optcse ();
7222798Smckusick 
7322798Smckusick if (debugflag[4]) showbuffer ();
7422798Smckusick 
7522798Smckusick if (! debugflag[7])
7622798Smckusick 	copyprop ();
7722798Smckusick 
7822798Smckusick if (debugflag[9]) showbuffer ();
7922798Smckusick 
8022798Smckusick for (sl = firstslot; sl; sl = nextsl)
8122798Smckusick 	{
8222798Smckusick 	nextsl = sl->next;
8322798Smckusick 	if (sl->type == SKFRTEMP)
8422798Smckusick 		{
8522798Smckusick 		templist = mkchain (sl->expr,templist);
8622798Smckusick 		sl->expr = NULL;
8722798Smckusick 		delslot (sl);
8822798Smckusick 		}
8922798Smckusick 	else
9022798Smckusick 		sl->expr = tempalloc (sl->expr);
9122798Smckusick 	}
9222798Smckusick 
9322798Smckusick if (! debugflag[10])
9422798Smckusick 	regalloc ();
9522798Smckusick 
9622798Smckusick flushopt ();
9722798Smckusick }
9822798Smckusick 
9922798Smckusick 
10022798Smckusick 
10122798Smckusick /*
10222798Smckusick  *  creates a new basic block record
10322798Smckusick  */
10422798Smckusick 
newblock(sl)10522798Smckusick LOCAL Bblockp newblock (sl)
10622798Smckusick Slotp	sl;
10722798Smckusick 
10822798Smckusick {
10922798Smckusick register Bblockp bb;
11022798Smckusick 
11122798Smckusick bb = ALLOC( bblock );
11222798Smckusick bb->next = NULL ;
11322798Smckusick if (lastblock)
11422798Smckusick 	{
11522798Smckusick 	bb->prev = lastblock;
11622798Smckusick 	lastblock->next = bb;
11722798Smckusick 	lastblock = bb;
11822798Smckusick 	}
11922798Smckusick else
12022798Smckusick 	{
12122798Smckusick 	firstblock = lastblock = bb;
12222798Smckusick 	bb->prev = NULL;
12322798Smckusick 	}
12422798Smckusick 
12522798Smckusick bb->first = sl;
12622798Smckusick return (bb);
12722798Smckusick }
12822798Smckusick 
12922798Smckusick 
13022798Smckusick 
13122798Smckusick /*
13222798Smckusick  *  scans slot buffer, creating basic block records
13322798Smckusick  */
13422798Smckusick 
formbblock()13522798Smckusick formbblock ()
13622798Smckusick 
13722798Smckusick {
13822798Smckusick Slotp	sl;
13922798Smckusick field	type;
14022798Smckusick Bblockp	newbb;
14122798Smckusick 
14222798Smckusick newbb = NULL;
14322798Smckusick for (sl = firstslot; sl; sl = sl->next)
14422798Smckusick 	{
14522798Smckusick 	type = sl->type;
14622798Smckusick 	switch (type)
14722798Smckusick 		{
14822798Smckusick 		case SKEQ:
14922798Smckusick 			if (!newbb)
15022798Smckusick 				newbb = newblock(sl);
15122798Smckusick 			if (containscall(sl->expr))
15222798Smckusick 				{
15322798Smckusick 				newbb->last = sl;
15422798Smckusick 				newbb = NULL;
15522798Smckusick 				}
15622798Smckusick 			break;
15722798Smckusick 		case SKNULL:
15822798Smckusick 		case SKASSIGN:
15922798Smckusick 		case SKFRTEMP:
16022798Smckusick 			if (!newbb)
16122798Smckusick 				newbb = newblock(sl);
16222798Smckusick 			break;
16322798Smckusick 		case SKPAUSE:
16422798Smckusick 		case SKSTOP:
16522798Smckusick 		case SKIFN:
16622798Smckusick 		case SKGOTO:
16722798Smckusick 		case SKCMGOTO:
16822798Smckusick 		case SKARIF:
16922798Smckusick 		case SKASGOTO:
17022798Smckusick 		case SKIOIFN:
17122798Smckusick 		case SKCALL:
17222798Smckusick 		case SKRETURN:
17322798Smckusick 			if (!newbb)
17422798Smckusick 				newbb = newblock(sl);
17522798Smckusick 			newbb->last = sl;
17622798Smckusick 			newbb = NULL;
17722798Smckusick 			break;
17822798Smckusick 		case SKLABEL:
17922798Smckusick 			if (newbb)
18022798Smckusick 				newbb->last = sl->prev;
18122798Smckusick 			newbb = newblock(sl);
18222798Smckusick 			break;
18322798Smckusick 		case SKDOHEAD:
18422798Smckusick 		case SKENDDO:
18522798Smckusick 			if (!newbb)
18622798Smckusick 				newbb = newblock(sl);
18722798Smckusick 			break;
18822798Smckusick 		default:
18922798Smckusick 			badthing("SKtype", "formbblock", type);
19022798Smckusick 			break;
19122798Smckusick 		}
19222798Smckusick 	}
19322798Smckusick if (newbb)
19422798Smckusick 	newbb->last = lastslot;
19522798Smckusick }
19622798Smckusick 
19722798Smckusick 
19822798Smckusick 
19922798Smckusick /*
20022798Smckusick  *  frees all basic block records
20122798Smckusick  *  as well as the id and value node chains hanging off the bb and their
20222798Smckusick  *  respective cross link chains (IDlist, DUPlist and NODElist structs)
20322798Smckusick  */
20422798Smckusick 
clearbb()20522798Smckusick clearbb ()
20622798Smckusick {
20722798Smckusick Bblockp	bb,next;
20822798Smckusick 
20922798Smckusick for (bb = firstblock; bb; bb = next)
21022798Smckusick 	{
21122798Smckusick 	next = bb->next;
21222798Smckusick 	   {
21322798Smckusick 	     idptr idp,next;
21422798Smckusick 	     for(idp = bb->headid; idp; idp = next)
21522798Smckusick 		{
21622798Smckusick 		 next = idp->next;
21722798Smckusick 		      {
21822798Smckusick 		      nodelptr nodelp, next;
21922798Smckusick 	              for(nodelp = idp->headnodelist; nodelp; nodelp = next)
22022798Smckusick 			 {
22122798Smckusick 			    next = nodelp->next;
22222798Smckusick 		            free( (charptr) nodelp);
22322798Smckusick 		         }
22422798Smckusick 		      }
22522798Smckusick                  free( (charptr) idp);
22622798Smckusick 	        }
22722798Smckusick            }
22822798Smckusick 	   {
22922798Smckusick 	     valuen vp,next;
23022798Smckusick 	     for(vp = bb->headnode; vp; vp = next)
23122798Smckusick 		{
23222798Smckusick 		 next = vp->next;
23322798Smckusick 		      {
23422798Smckusick 		      idlptr idlp, next;
23522798Smckusick 	              for(idlp = vp->headdeplist; idlp; idlp = next)
23622798Smckusick 			 {
23722798Smckusick 			    next = idlp->next;
23822798Smckusick 		            free( (charptr) idlp);
23922798Smckusick 		         }
24022798Smckusick 		      }
24122798Smckusick 		      {
24222798Smckusick 		      duplptr duplp, next;
24322798Smckusick 	              for(duplp = vp->headduplist; duplp; duplp = next)
24422798Smckusick 			 {
24522798Smckusick 			    next = duplp->next;
24622798Smckusick 		            free( (charptr) duplp);
24722798Smckusick 		         }
24822798Smckusick 		      }
24922798Smckusick                  free( (charptr) vp);
25022798Smckusick 	        }
25122798Smckusick            }
25222798Smckusick 	free ( (charptr) bb);
25322798Smckusick 	}
25422798Smckusick firstblock = lastblock = NULL;
25522798Smckusick }
25622798Smckusick 
25722798Smckusick 
25822798Smckusick /* structure for maintaining records on copy statements */
25922798Smckusick 
26022798Smckusick typedef struct Subrec {
26122798Smckusick 	Addrp	lmem;
26222798Smckusick 	Addrp	rmem;
26322798Smckusick 	int	sets;
26422798Smckusick } *Subrecp;
26522798Smckusick 
26622798Smckusick 
26722798Smckusick LOCAL chainp sublist;	/* list of copy statements */
26822798Smckusick LOCAL int prop1count;	/* count of number of temporaries eliminated */
26922798Smckusick LOCAL int prop2count;	/* count of number of uses of temporaries replaced */
27022798Smckusick 
27122798Smckusick expptr rmcommaop();
27222798Smckusick Addrp subfor();
27322798Smckusick 
27422798Smckusick 
27522798Smckusick 
27622798Smckusick /*
27722798Smckusick  *  eliminates copy statements of the form T1 = T2 from the intermediate
27822798Smckusick  *  code, where T1 and T2 are temporary variables which are each
27922798Smckusick  *  set only once;  eliminates the copy statement and replaces each
28022798Smckusick  *  use of T1 by T2 (T1 is therefore totally eliminated).
28122798Smckusick  */
28222798Smckusick 
copyprop()28322798Smckusick LOCAL copyprop ()
28422798Smckusick 
28522798Smckusick {
28622798Smckusick Slotp	sl,nextsl;
28722798Smckusick expptr	expr;
28822798Smckusick Tempp	lp,rp;
28922798Smckusick 
29022798Smckusick for (sl = firstslot; sl; sl = sl->next)
29122798Smckusick 	sl->expr = rmcommaop (sl->expr,sl);
29222798Smckusick 
29322798Smckusick prop1count = prop2count = 0;
29422798Smckusick findcopies ();
29522798Smckusick 
29622798Smckusick for (sl = firstslot; sl; sl = nextsl)
29722798Smckusick 	{
29822798Smckusick 	nextsl = sl->next;
29922798Smckusick 	expr = sl->expr;
30022798Smckusick 
30122798Smckusick 	if ((sl->type == SKFRTEMP) && subfor (expr))
30222798Smckusick 		{
30322798Smckusick 		delslot (sl);
30422798Smckusick 		expr = ENULL;
30522798Smckusick 		}
30622798Smckusick 	else if (expr && expr->tag == TEXPR &&
30722798Smckusick 			expr->exprblock.opcode == OPASSIGN)
30822798Smckusick 		{
30922798Smckusick 		lp = (Tempp) expr->exprblock.leftp;
31022798Smckusick 		rp = (Tempp) expr->exprblock.rightp;
31122798Smckusick 		if (lp->tag == TTEMP && rp->tag == TTEMP)
31222798Smckusick 			if (subfor(lp->memalloc) == rp->memalloc
31322798Smckusick 					&& !subfor (rp->memalloc))
31422798Smckusick 				{
31522798Smckusick 				frexpr (expr);
31622798Smckusick 				expr = sl->expr = ENULL;
31722798Smckusick 				prop1count++;
31822798Smckusick 				}
31922798Smckusick 		}
32022798Smckusick 
32122798Smckusick 	propagate (expr);
32222798Smckusick 	}
32322798Smckusick 
32422798Smckusick if (debugflag[0])
32522798Smckusick 	fprintf (diagfile,
32622798Smckusick 	    "%d temporarie%s replaced by copy propagation (%d use%s)\n",
32722798Smckusick 		prop1count,(prop1count==1 ? "" : "s"),
32822798Smckusick 		prop2count,(prop2count==1 ? "" : "s") );
32922798Smckusick }
33022798Smckusick 
33122798Smckusick 
33222798Smckusick 
33322798Smckusick /*
33422798Smckusick  *  finds copy statements and enters information in table
33522798Smckusick  */
33622798Smckusick 
findcopies()33722798Smckusick LOCAL findcopies ()
33822798Smckusick 
33922798Smckusick {
34022798Smckusick Slotp	sl;
34122798Smckusick expptr	expr;
34222798Smckusick chainp	cp;
34322798Smckusick 
34422798Smckusick for (sl = firstslot; sl; sl = sl->next)
34522798Smckusick 	{
34622798Smckusick 	expr = sl->expr;
34722798Smckusick 	if (expr) switch (expr->tag)
34822798Smckusick 	    {
34922798Smckusick 	    case TEXPR:
35022798Smckusick 		ckexpr (expr);
35122798Smckusick 		break;
35222798Smckusick 
35322798Smckusick 	    case TLIST:
35422798Smckusick 		for (cp = expr->listblock.listp; cp; cp = cp->nextp)
35522798Smckusick 			{
35622798Smckusick 			expr = (expptr) cp->datap;
35722798Smckusick 			ckexpr (expr);
35822798Smckusick 			}
35922798Smckusick 		break;
36022798Smckusick 
36122798Smckusick 	    default:
36222798Smckusick 		break;
36322798Smckusick 	    }
36422798Smckusick 	}
36522798Smckusick }
36622798Smckusick 
36722798Smckusick 
36822798Smckusick 
36922798Smckusick /*
37022798Smckusick  *  checks an individual expression
37122798Smckusick  */
37222798Smckusick 
ckexpr(expr)37322798Smckusick ckexpr (expr)
37422798Smckusick expptr	expr;
37522798Smckusick 
37622798Smckusick {
37722798Smckusick Tempp	lp,rp;
37822798Smckusick int	oc = expr->exprblock.opcode;
37922798Smckusick 
38022798Smckusick if (oc == OPASSIGN || oc == OPPLUSEQ || oc == OPSTAREQ)
38122798Smckusick 	{
38222798Smckusick 	lp = (Tempp) expr->exprblock.leftp;
38322798Smckusick 	rp = (Tempp) expr->exprblock.rightp;
38422798Smckusick 	if (lp->tag == TTEMP)
38522798Smckusick 		if (rp->tag == TTEMP && oc == OPASSIGN)
38622798Smckusick 			enter (lp->memalloc, rp->memalloc);
38722798Smckusick 		else
38822798Smckusick 			enter (lp->memalloc, ENULL);
38922798Smckusick 	}
39022798Smckusick }
39122798Smckusick 
39222798Smckusick 
39322798Smckusick 
39422798Smckusick /*
39522798Smckusick  *  Enters the given memalloc values in the table (or update if they
39622798Smckusick  *  are already there), for the assignment statement m1 = m2.
39722798Smckusick  *  If m2 is NULL, this indicates that the assignment is not a copy
39822798Smckusick  *  statement.
39922798Smckusick  */
40022798Smckusick 
enter(m1,m2)40122798Smckusick LOCAL enter (m1,m2)
40222798Smckusick Addrp	m1,m2;
40322798Smckusick 
40422798Smckusick {
40522798Smckusick chainp	cp;
40622798Smckusick Subrecp old,new;
40722798Smckusick 
40822798Smckusick for (cp = sublist; cp; cp = cp->nextp)
40922798Smckusick 	{
41022798Smckusick 	old = (Subrecp) cp->datap;
41122798Smckusick 	if (old->lmem == m1)
41222798Smckusick 		{
41322798Smckusick 		old->sets++;
41422798Smckusick 		return;
41522798Smckusick 		}
41622798Smckusick 	}
41722798Smckusick 
41822798Smckusick new = ALLOC (Subrec);
41922798Smckusick new->lmem = m1;
42022798Smckusick new->rmem = m2;
42122798Smckusick new->sets = 1;
42222798Smckusick sublist = mkchain (new, sublist);
42322798Smckusick }
42422798Smckusick 
42522798Smckusick 
42622798Smckusick 
42722798Smckusick /*
42822798Smckusick  *  looks for record for the given memalloc value
42922798Smckusick  */
43022798Smckusick 
lookup(mem)43122798Smckusick LOCAL Subrecp lookup (mem)
43222798Smckusick Addrp	mem;
43322798Smckusick 
43422798Smckusick {
43522798Smckusick chainp	cp;
43622798Smckusick Subrecp rec;
43722798Smckusick 
43822798Smckusick for (cp = sublist; cp; cp = cp->nextp)
43922798Smckusick 	{
44022798Smckusick 	rec = (Subrecp) cp->datap;
44122798Smckusick 	if (rec->lmem == mem)
44222798Smckusick 		return rec;
44322798Smckusick 	}
44422798Smckusick 
44522798Smckusick return NULL;
44622798Smckusick }
44722798Smckusick 
44822798Smckusick 
44922798Smckusick 
45022798Smckusick /*
45122798Smckusick  *  checks to see if there is a substitute for given memalloc value
45222798Smckusick  */
45322798Smckusick 
subfor(mem)45422798Smckusick LOCAL Addrp subfor (mem)
45522798Smckusick Addrp	mem;
45622798Smckusick 
45722798Smckusick {
45822798Smckusick Subrecp rec,rec2;
45922798Smckusick Addrp	sub;
46022798Smckusick 
46122798Smckusick rec = lookup (mem);
46222798Smckusick if (rec && rec->sets == 1)
46322798Smckusick 	{
46422798Smckusick 	sub = rec->rmem;
46522798Smckusick 	rec2 = lookup(sub);
46622798Smckusick 	if (rec2 && rec2->sets == 1)
46722798Smckusick 		return sub;
46822798Smckusick 	}
46922798Smckusick 
47022798Smckusick return NULL;
47122798Smckusick }
47222798Smckusick 
47322798Smckusick 
47422798Smckusick 
47522798Smckusick /*
47622798Smckusick  *  actually propagates the information
47722798Smckusick  */
47822798Smckusick 
propagate(expr)47922798Smckusick LOCAL propagate (expr)
48022798Smckusick expptr	expr;
48122798Smckusick 
48222798Smckusick {
48322798Smckusick chainp	t;
48422798Smckusick Addrp	new;
48522798Smckusick 
48622798Smckusick if (! expr) return;
48722798Smckusick 
48822798Smckusick switch (expr->tag)
48922798Smckusick 	{
49022798Smckusick 	case TEXPR:
49122798Smckusick 		propagate (expr->exprblock.leftp);
49222798Smckusick 		propagate (expr->exprblock.rightp);
49322798Smckusick 		break;
49422798Smckusick 
49522798Smckusick 	case TADDR:
49622798Smckusick 		propagate (expr->addrblock.vleng);
49722798Smckusick 		propagate (expr->addrblock.memoffset);
49822798Smckusick 		break;
49922798Smckusick 
50022798Smckusick 	case TLIST:
50122798Smckusick 		for (t = expr->listblock.listp; t; t = t->nextp)
50222798Smckusick 			propagate (t->datap);
50322798Smckusick 		break;
50422798Smckusick 
50522798Smckusick 	case TTEMP:
50622798Smckusick 		new = subfor (expr->tempblock.memalloc);
50722798Smckusick 		if (new)
50822798Smckusick 			{
50922798Smckusick 			expr->tempblock.memalloc = new;
51022798Smckusick 			prop2count++;
51122798Smckusick 			}
51222798Smckusick 		break;
51322798Smckusick 
51422798Smckusick 	default:
51522798Smckusick 		break;
51622798Smckusick 	}
51722798Smckusick }
51822798Smckusick 
51922798Smckusick 
52022798Smckusick 
52122798Smckusick /*
52222798Smckusick  *  allocates ADDR blocks for each TEMP in the expression
52322798Smckusick  */
52422798Smckusick 
tempalloc(expr)52522798Smckusick LOCAL expptr tempalloc (expr)
52622798Smckusick expptr	expr;
52722798Smckusick 
52822798Smckusick {
52922798Smckusick chainp	t;
53022798Smckusick 
53122798Smckusick if (! expr)
53222798Smckusick 	return NULL;
53322798Smckusick 
53422798Smckusick switch (expr->tag)
53522798Smckusick     {
53622798Smckusick     case TEXPR:
53722798Smckusick 	expr->exprblock.leftp = tempalloc (expr->exprblock.leftp);
53822798Smckusick 	expr->exprblock.rightp = tempalloc (expr->exprblock.rightp);
53922798Smckusick 	break;
54022798Smckusick 
54122798Smckusick     case TADDR:
54222798Smckusick 	expr->addrblock.vleng = tempalloc (expr->addrblock.vleng);
54322798Smckusick 	expr->addrblock.memoffset = tempalloc (expr->addrblock.memoffset);
54422798Smckusick 	break;
54522798Smckusick 
54622798Smckusick     case TLIST:
54722798Smckusick 	for (t = expr->listblock.listp; t; t = t->nextp)
54822798Smckusick 		t->datap = (tagptr) tempalloc (t->datap);
54922798Smckusick 	break;
55022798Smckusick 
55122798Smckusick     case TTEMP:
55226510Sdonn 	expr->tempblock.vleng = tempalloc (expr->tempblock.vleng);
55322798Smckusick 	return (expptr) cpexpr (altmpn (expr));
55422798Smckusick 	break;
55522798Smckusick 
55622798Smckusick     default:
55722798Smckusick 	break;
55822798Smckusick     }
55922798Smckusick return expr;
56022798Smckusick }
56122798Smckusick 
56222798Smckusick 
56322798Smckusick /********************* debugging routines *********************/
56422798Smckusick 
56522798Smckusick 
56622798Smckusick 
Announce(s,q)56722798Smckusick Announce (s,q)
56822798Smckusick char *s;
56922798Smckusick expptr q;
57022798Smckusick 
57122798Smckusick {
57222798Smckusick fprintf (diagfile,"\nAn expression [%s]----->\n",s);
57322798Smckusick showexpr(q,0);
57422798Smckusick fprintf (diagfile,"\n-------------end of expr--------------\n");
57522798Smckusick }
57622798Smckusick 
57722798Smckusick 
57822798Smckusick 
57922798Smckusick /*
58022798Smckusick  *  dump the basic block buffer, including expressions, mnemonically
58122798Smckusick  */
58222798Smckusick 
showbuffer()58322798Smckusick showbuffer ()
58422798Smckusick 
58522798Smckusick {
58622798Smckusick Slotp	sl;
58722798Smckusick Bblockp	bb;
58822798Smckusick int	i;
58922798Smckusick 
59022798Smckusick fprintf (diagfile,"Basic blocks with first and last slots ----------\n");
59122798Smckusick for (i=1, bb = firstblock; bb; i++, bb = bb->next)
59222798Smckusick 	fprintf (diagfile,"%2d.  %d  %d\n",i,bb->first,bb->last);
59322798Smckusick fprintf (diagfile,"\n");
59422798Smckusick 
59522798Smckusick fprintf (diagfile,"Slots and expressions ----------\n");
59622798Smckusick 
59722798Smckusick fprintf (diagfile,"tag pointer vtype vclass vstg vleng\n");
59822798Smckusick fprintf (diagfile,"          ADDR memno memoffset istemp ntempelt varleng\n");
59922798Smckusick fprintf (diagfile,"          TEMP memalloc istemp ntempelt varleng\n");
60022798Smckusick fprintf (diagfile,"          EXPR opcode leftp rightp\n");
60122798Smckusick fprintf (diagfile,"          LIST type listp\n");
60222798Smckusick fprintf (diagfile,"\n");
60322798Smckusick 
60422798Smckusick for (i=1, sl = firstslot; sl; i++, sl = sl->next)
60522798Smckusick 	{
60622798Smckusick 	fprintf (diagfile,"%2d.  ",i);
60722798Smckusick 	showslt (sl);
60822798Smckusick 	}
60922798Smckusick fprintf (diagfile,"---------- End of showbuffer ----------\n");
61022798Smckusick }
61122798Smckusick 
61222798Smckusick 
61322798Smckusick 
61422798Smckusick /*
61522798Smckusick  *  dumps a single slot in the code buffer
61622798Smckusick  */
61722798Smckusick 
61822798Smckusick LOCAL charptr Zslot[] = {"NULL",
61922798Smckusick 	"IFN","GOTO","LABEL","EQ","CALL","CMGOTO","STOP","DOHEAD",
62022798Smckusick 	"ENDDO","ARIF","RETURN","ASGOTO","PAUSE","ASSIGN","IOIFN","FRTEMP"};
62122798Smckusick 
62222798Smckusick 
62322798Smckusick 
showslt(sl)62422798Smckusick showslt (sl)
62522798Smckusick Slotp sl;
62622798Smckusick 
62722798Smckusick {
62822798Smckusick fprintf (diagfile,"(%2d)  %d  %s  %d\n",
62922798Smckusick 	sl->lineno,sl,Zslot[sl->type],sl->label);
63022798Smckusick showexpr (sl->expr,0);
63122798Smckusick fprintf (diagfile,"\n");
63222798Smckusick }
63322798Smckusick 
63422798Smckusick 
63522798Smckusick 
showslottype(type)63622798Smckusick showslottype (type)
63722798Smckusick int type;
63822798Smckusick 
63922798Smckusick {
64022798Smckusick fprintf (diagfile,"%s\n",Zslot[type]);
64122798Smckusick }
64222798Smckusick 
64322798Smckusick 
64422798Smckusick 
64522798Smckusick /*
64622798Smckusick  *  displays the given expression at the given indentation, showing
64722798Smckusick  *  its subexpressions at further indentations
64822798Smckusick  */
64922798Smckusick 
65022798Smckusick LOCAL charptr Ztag[] = {"----",
65122798Smckusick 	"NAME","CONST","EXPR","ADDR","TEMP","PRIM","LIST","IMPLDO","ERROR"};
65222798Smckusick LOCAL charptr Zstg[] = {"unk",
65322798Smckusick 	"ARG","AUTO","BSS","INIT","CONST","EXT","INTR","STFUNCT",
65422798Smckusick 	"COMMON","EQUIV","REG","LENG","NULL","PREG"};
65522798Smckusick LOCAL charptr Zclass[] = {"unk",
65622798Smckusick 	"PARAM","VAR","ENTRY","MAIN","BLOCK","PROC","NAMELIST"};
65722798Smckusick LOCAL charptr Zop[] = {"----",
65822798Smckusick 	"PLUS","MINUS","STAR","SLASH","POWER","NEG","OR","AND","EQV",
65922798Smckusick 	"NEQV","NOT","CONCAT","LT","EQ","GT","LE","NE","GE","CALL",
66022798Smckusick 	"CCALL","ASSIGN","PLUSEQ","STAREQ","CONV","LSHIFT","MOD",
66122798Smckusick 	"COMMA","QUEST","COLON","ABS","MIN","MAX","ADDR","INDIRECT",
66222798Smckusick 	"BITOR","BITAND","BITXOR","BITNOT","RSHIFT","PAREN"};
66322798Smckusick LOCAL charptr Ztype[] = {"unk",
66422798Smckusick 	"ADDR","SHORT","LONG","REAL","DREAL","COMPLEX","DCOMPLEX",
66522798Smckusick 	"LOGICAL","CHAR","SUBR","ERROR"};
66622798Smckusick 
66722798Smckusick 
showexpr(p,indent)66822798Smckusick showexpr(p,indent)
66922798Smckusick tagptr p;
67022798Smckusick int indent;
67122798Smckusick 
67222798Smckusick {
67322798Smckusick int i;
67422798Smckusick int type;
67522798Smckusick chainp q;
67622798Smckusick 
67722798Smckusick #define PRHEAD(q) fprintf(diagfile,"%s %d %s %s %s %d", \
67822798Smckusick 	Ztag[q->tag], q, Ztype[q->headblock.vtype], \
67922798Smckusick 	Zclass[q->headblock.vclass], Zstg[q->headblock.vstg], \
68022798Smckusick 	q->headblock.vleng);
68122798Smckusick #define SHOWEXPR(p) showexpr(p,indent+2)
68222798Smckusick 
68322798Smckusick 
68422798Smckusick 
68522798Smckusick if(p == NULL)
68622798Smckusick 	return;
68722798Smckusick 
68822798Smckusick for (i=0; i<indent; i++)
68922798Smckusick 	putc(' ',diagfile);
69022798Smckusick 
69122798Smckusick switch(p->tag)
69222798Smckusick          {
69322798Smckusick          case TCONST:
69422798Smckusick               PRHEAD(p);
69522798Smckusick 
69622798Smckusick               type=p->constblock.vtype;
69722798Smckusick               if (ISCHAR(p))
69822798Smckusick                  {
69922798Smckusick                       fprintf(diagfile," ISCHAR ccp= %d\n",
70033256Sbostic                                                    p->constblock.constant.ccp);
70122798Smckusick                       SHOWEXPR(p->constblock.vleng);
70222798Smckusick                  }
70322798Smckusick               else  if( ISINT(type) )
70433256Sbostic                    fprintf(diagfile," ci= %d\n",p->constblock.constant.ci);
70522798Smckusick               else if( ISREAL(type) )
70633256Sbostic                    fprintf(diagfile," cd[0]= %e\n",p->constblock.constant.cd[0]);
70722798Smckusick               else fprintf(diagfile," cd[0]= %e  cd[1]= %e\n",
70833256Sbostic                             p->constblock.constant.cd[0],
70933256Sbostic                             p->constblock.constant.cd[1] );
71022798Smckusick               break;
71122798Smckusick 
71222798Smckusick          case TADDR:
71322798Smckusick               PRHEAD(p);
71422798Smckusick               fprintf(diagfile,
71522798Smckusick               " memno= %d %d %d %d %d\n",
71622798Smckusick               p->addrblock.memno,p->addrblock.memoffset,p->addrblock.istemp,
71722798Smckusick               p->addrblock.ntempelt,p->addrblock.varleng);
71822798Smckusick               SHOWEXPR(p->addrblock.vleng);
71922798Smckusick               SHOWEXPR(p->addrblock.memoffset);
72022798Smckusick               break;
72122798Smckusick 
72222798Smckusick          case TTEMP:
72322798Smckusick 	      fprintf(diagfile,"%s %d %s %s %d",
72422798Smckusick 			Ztag[p->tag], p, Ztype[p->headblock.vtype],
72522798Smckusick 			Zclass[p->headblock.vclass],
72622798Smckusick 			p->headblock.vleng);
72722798Smckusick               fprintf(diagfile,
72822798Smckusick 		" memalloc= %d %d %d %d\n",
72922798Smckusick 		p->tempblock.memalloc,p->tempblock.istemp,
73022798Smckusick 		p->tempblock.ntempelt,p->tempblock.varleng);
73122798Smckusick               SHOWEXPR(p->tempblock.vleng);
73222798Smckusick 	      SHOWEXPR(p->tempblock.memalloc);
73322798Smckusick               break;
73422798Smckusick 
73522798Smckusick          case TERROR:
73622798Smckusick               fprintf(diagfile,"ERROR %d\n",p);
73722798Smckusick               break;
73822798Smckusick 
73922798Smckusick          case TNAME:
74022798Smckusick               fprintf(diagfile,"NAME %d\n",p);
74122798Smckusick               return;
74222798Smckusick 
74322798Smckusick          case TPRIM:
74422798Smckusick               fprintf(diagfile,"PRIM %d --- not implemented\n",p);
74522798Smckusick               break;
74622798Smckusick 
74722798Smckusick          case TEXPR:
74822798Smckusick               PRHEAD(p);
74922798Smckusick               fprintf(diagfile," opcode= %s %d %d\n",
75022798Smckusick                      Zop[p->exprblock.opcode],p->exprblock.leftp,
75122798Smckusick                      p->exprblock.rightp);
75222798Smckusick               SHOWEXPR(p->exprblock.leftp);
75322798Smckusick               if(p->exprblock.rightp)
75422798Smckusick                     SHOWEXPR(p->exprblock.rightp);
75522798Smckusick               break;
75622798Smckusick 
75722798Smckusick          case TLIST:
75822798Smckusick               fprintf(diagfile,"LIST %d %s %d\n",p,
75922798Smckusick                       Ztype[p->listblock.vtype],p->listblock.listp);
76022798Smckusick               for(q= p->listblock.listp ; q ; q = q->nextp)
76122798Smckusick                       SHOWEXPR(q->datap);
76222798Smckusick 	      for (i=0; i<indent; i++)
76322798Smckusick 		putc (' ',diagfile);
76422798Smckusick               fprintf(diagfile,"END LIST %d\n",p);
76522798Smckusick               break;
76622798Smckusick 
76722798Smckusick          default:
76822798Smckusick               fprintf(diagfile,"showexpr BAD TAG= %d at %d \n",p->tag,p);
76922798Smckusick            }
77022798Smckusick }
77122798Smckusick 
77222798Smckusick 
77322798Smckusick 
selective()77422798Smckusick selective()/************************************/
77522798Smckusick {
77622798Smckusick int i;
77722798Smckusick Slotp sl;
77822798Smckusick 
77922798Smckusick i=0;
78022798Smckusick fprintf (stderr,"SELECTIVE OUTPUT\n");
78122798Smckusick for (sl=firstslot;sl;sl=sl->next)
78222798Smckusick 	{
78322798Smckusick 	i++;
78422798Smckusick 	if (i>=176 && i<184)
78522798Smckusick 		{
78622798Smckusick 		fprintf (stderr,"%d.  ",i);
78722798Smckusick 		showslt(sl);
78822798Smckusick 		}
78922798Smckusick 	}
79022798Smckusick }
79122798Smckusick 
79222798Smckusick 
79322798Smckusick 
79422798Smckusick 
containscall(p)79522798Smckusick LOCAL containscall(p)
79622798Smckusick expptr p;
79722798Smckusick {
79822798Smckusick   chainp cp;
79922798Smckusick 
80022798Smckusick   if (p == NULL)
80122798Smckusick     return NO;
80222798Smckusick 
80322798Smckusick   switch (p->tag)
80422798Smckusick     {
80522798Smckusick     case TADDR:
80622798Smckusick       if (containscall(p->addrblock.vleng)
80722798Smckusick 	  || containscall(p->addrblock.memoffset))
80822798Smckusick 	return YES;
80922798Smckusick       else
81022798Smckusick         return NO;
81122798Smckusick 
81222798Smckusick     case TCONST:
81322798Smckusick       return NO;
81422798Smckusick 
81522798Smckusick     case TERROR:
81622798Smckusick       return NO;
81722798Smckusick 
81822798Smckusick     case TEXPR:
81922798Smckusick       if (p->exprblock.opcode == OPCALL ||
82022798Smckusick 	  p->exprblock.opcode == OPCCALL)
82122798Smckusick 	return YES;
82222798Smckusick       if (containscall(p->exprblock.vleng) ||
82322798Smckusick 	  containscall(p->exprblock.leftp) ||
82422798Smckusick 	  containscall(p->exprblock.rightp))
82522798Smckusick 	return YES;
82622798Smckusick       else
82722798Smckusick 	return NO;
82822798Smckusick 
82922798Smckusick     case TLIST:
83022798Smckusick       cp = p->listblock.listp;
83122798Smckusick       while (cp)
83222798Smckusick 	{
83322798Smckusick 	  if (containscall(cp->datap))
83422798Smckusick 	    return YES;
83522798Smckusick 	  cp = cp->nextp;
83622798Smckusick 	}
83722798Smckusick       return NO;
83822798Smckusick 
83922798Smckusick     default:
84022798Smckusick       return YES;
84122798Smckusick     }
84222798Smckusick }
843