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