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