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