1*22798Smckusick /* 2*22798Smckusick * Copyright (c) 1980 Regents of the University of California. 3*22798Smckusick * All rights reserved. The Berkeley software License Agreement 4*22798Smckusick * specifies the terms and conditions for redistribution. 5*22798Smckusick */ 6*22798Smckusick 7*22798Smckusick #ifndef lint 8*22798Smckusick static char sccsid[] = "@(#)bb.c 5.1 (Berkeley) 06/07/85"; 9*22798Smckusick #endif not lint 10*22798Smckusick 11*22798Smckusick /* 12*22798Smckusick * bb.c 13*22798Smckusick * 14*22798Smckusick * Basic block optimizations. 15*22798Smckusick * 16*22798Smckusick * University of Utah CS Dept modification history: 17*22798Smckusick * 18*22798Smckusick * Revision 2.1 84/07/19 12:01:20 donn 19*22798Smckusick * Changed comment headers for UofU. 20*22798Smckusick * 21*22798Smckusick * Revision 1.2 84/04/02 14:22:49 donn 22*22798Smckusick * Bug in copy propagation missed places where temporaries are assigned to 23*22798Smckusick * by OPSTAREQ or OPPLUSEQ, e.g. exponentiation with an integer constant 24*22798Smckusick * power, expanded inline. 25*22798Smckusick * 26*22798Smckusick */ 27*22798Smckusick 28*22798Smckusick #include "defs.h" 29*22798Smckusick #include "optim.h" 30*22798Smckusick 31*22798Smckusick /* 32*22798Smckusick * This file contains code for determination of basic blocks, 33*22798Smckusick * as well as some other optimization supporting routines 34*22798Smckusick * [including the main routine 'optimize()']. 35*22798Smckusick * 36*22798Smckusick * The compiler's general debugging flag ['debugflag'] has been 37*22798Smckusick * extended to provide the capability of having multiple flags 38*22798Smckusick * which are contained in an array. If the option -d is used, 39*22798Smckusick * then the flag debugflag[0] is set. If a sequence of one or more 40*22798Smckusick * numbers are given (e.g, -d3,7,12), then the flags debugflag[3], 41*22798Smckusick * debugflag[7], and debugflag[12] are set. The maximum number of 42*22798Smckusick * flags available is specified in the defines.h file. 43*22798Smckusick */ 44*22798Smckusick 45*22798Smckusick 46*22798Smckusick Bblockp firstblock = NULL; /* first block in buffer */ 47*22798Smckusick Bblockp lastblock = NULL; /* last block in buffer */ 48*22798Smckusick 49*22798Smckusick expptr tempalloc(); 50*22798Smckusick 51*22798Smckusick 52*22798Smckusick optimize () 53*22798Smckusick 54*22798Smckusick { 55*22798Smckusick Bblockp bb; 56*22798Smckusick Slotp sl,nextsl; 57*22798Smckusick 58*22798Smckusick if (debugflag[2]) showbuffer (); 59*22798Smckusick 60*22798Smckusick optloops (); 61*22798Smckusick 62*22798Smckusick if (debugflag[3]) showbuffer (); 63*22798Smckusick 64*22798Smckusick formbblock (); 65*22798Smckusick optcse (); 66*22798Smckusick 67*22798Smckusick if (debugflag[4]) showbuffer (); 68*22798Smckusick 69*22798Smckusick if (! debugflag[7]) 70*22798Smckusick copyprop (); 71*22798Smckusick 72*22798Smckusick if (debugflag[9]) showbuffer (); 73*22798Smckusick 74*22798Smckusick for (sl = firstslot; sl; sl = nextsl) 75*22798Smckusick { 76*22798Smckusick nextsl = sl->next; 77*22798Smckusick if (sl->type == SKFRTEMP) 78*22798Smckusick { 79*22798Smckusick templist = mkchain (sl->expr,templist); 80*22798Smckusick sl->expr = NULL; 81*22798Smckusick delslot (sl); 82*22798Smckusick } 83*22798Smckusick else 84*22798Smckusick sl->expr = tempalloc (sl->expr); 85*22798Smckusick } 86*22798Smckusick 87*22798Smckusick if (! debugflag[10]) 88*22798Smckusick regalloc (); 89*22798Smckusick 90*22798Smckusick flushopt (); 91*22798Smckusick } 92*22798Smckusick 93*22798Smckusick 94*22798Smckusick 95*22798Smckusick /* 96*22798Smckusick * creates a new basic block record 97*22798Smckusick */ 98*22798Smckusick 99*22798Smckusick LOCAL Bblockp newblock (sl) 100*22798Smckusick Slotp sl; 101*22798Smckusick 102*22798Smckusick { 103*22798Smckusick register Bblockp bb; 104*22798Smckusick 105*22798Smckusick bb = ALLOC( bblock ); 106*22798Smckusick bb->next = NULL ; 107*22798Smckusick if (lastblock) 108*22798Smckusick { 109*22798Smckusick bb->prev = lastblock; 110*22798Smckusick lastblock->next = bb; 111*22798Smckusick lastblock = bb; 112*22798Smckusick } 113*22798Smckusick else 114*22798Smckusick { 115*22798Smckusick firstblock = lastblock = bb; 116*22798Smckusick bb->prev = NULL; 117*22798Smckusick } 118*22798Smckusick 119*22798Smckusick bb->first = sl; 120*22798Smckusick return (bb); 121*22798Smckusick } 122*22798Smckusick 123*22798Smckusick 124*22798Smckusick 125*22798Smckusick /* 126*22798Smckusick * scans slot buffer, creating basic block records 127*22798Smckusick */ 128*22798Smckusick 129*22798Smckusick formbblock () 130*22798Smckusick 131*22798Smckusick { 132*22798Smckusick Slotp sl; 133*22798Smckusick field type; 134*22798Smckusick Bblockp newbb; 135*22798Smckusick 136*22798Smckusick newbb = NULL; 137*22798Smckusick for (sl = firstslot; sl; sl = sl->next) 138*22798Smckusick { 139*22798Smckusick type = sl->type; 140*22798Smckusick switch (type) 141*22798Smckusick { 142*22798Smckusick case SKEQ: 143*22798Smckusick if (!newbb) 144*22798Smckusick newbb = newblock(sl); 145*22798Smckusick if (containscall(sl->expr)) 146*22798Smckusick { 147*22798Smckusick newbb->last = sl; 148*22798Smckusick newbb = NULL; 149*22798Smckusick } 150*22798Smckusick break; 151*22798Smckusick case SKNULL: 152*22798Smckusick case SKASSIGN: 153*22798Smckusick case SKFRTEMP: 154*22798Smckusick if (!newbb) 155*22798Smckusick newbb = newblock(sl); 156*22798Smckusick break; 157*22798Smckusick case SKPAUSE: 158*22798Smckusick case SKSTOP: 159*22798Smckusick case SKIFN: 160*22798Smckusick case SKGOTO: 161*22798Smckusick case SKCMGOTO: 162*22798Smckusick case SKARIF: 163*22798Smckusick case SKASGOTO: 164*22798Smckusick case SKIOIFN: 165*22798Smckusick case SKCALL: 166*22798Smckusick case SKRETURN: 167*22798Smckusick if (!newbb) 168*22798Smckusick newbb = newblock(sl); 169*22798Smckusick newbb->last = sl; 170*22798Smckusick newbb = NULL; 171*22798Smckusick break; 172*22798Smckusick case SKLABEL: 173*22798Smckusick if (newbb) 174*22798Smckusick newbb->last = sl->prev; 175*22798Smckusick newbb = newblock(sl); 176*22798Smckusick break; 177*22798Smckusick case SKDOHEAD: 178*22798Smckusick case SKENDDO: 179*22798Smckusick if (!newbb) 180*22798Smckusick newbb = newblock(sl); 181*22798Smckusick break; 182*22798Smckusick default: 183*22798Smckusick badthing("SKtype", "formbblock", type); 184*22798Smckusick break; 185*22798Smckusick } 186*22798Smckusick } 187*22798Smckusick if (newbb) 188*22798Smckusick newbb->last = lastslot; 189*22798Smckusick } 190*22798Smckusick 191*22798Smckusick 192*22798Smckusick 193*22798Smckusick /* 194*22798Smckusick * frees all basic block records 195*22798Smckusick * as well as the id and value node chains hanging off the bb and their 196*22798Smckusick * respective cross link chains (IDlist, DUPlist and NODElist structs) 197*22798Smckusick */ 198*22798Smckusick 199*22798Smckusick clearbb () 200*22798Smckusick { 201*22798Smckusick Bblockp bb,next; 202*22798Smckusick 203*22798Smckusick for (bb = firstblock; bb; bb = next) 204*22798Smckusick { 205*22798Smckusick next = bb->next; 206*22798Smckusick { 207*22798Smckusick idptr idp,next; 208*22798Smckusick for(idp = bb->headid; idp; idp = next) 209*22798Smckusick { 210*22798Smckusick next = idp->next; 211*22798Smckusick { 212*22798Smckusick nodelptr nodelp, next; 213*22798Smckusick for(nodelp = idp->headnodelist; nodelp; nodelp = next) 214*22798Smckusick { 215*22798Smckusick next = nodelp->next; 216*22798Smckusick free( (charptr) nodelp); 217*22798Smckusick } 218*22798Smckusick } 219*22798Smckusick free( (charptr) idp); 220*22798Smckusick } 221*22798Smckusick } 222*22798Smckusick { 223*22798Smckusick valuen vp,next; 224*22798Smckusick for(vp = bb->headnode; vp; vp = next) 225*22798Smckusick { 226*22798Smckusick next = vp->next; 227*22798Smckusick { 228*22798Smckusick idlptr idlp, next; 229*22798Smckusick for(idlp = vp->headdeplist; idlp; idlp = next) 230*22798Smckusick { 231*22798Smckusick next = idlp->next; 232*22798Smckusick free( (charptr) idlp); 233*22798Smckusick } 234*22798Smckusick } 235*22798Smckusick { 236*22798Smckusick duplptr duplp, next; 237*22798Smckusick for(duplp = vp->headduplist; duplp; duplp = next) 238*22798Smckusick { 239*22798Smckusick next = duplp->next; 240*22798Smckusick free( (charptr) duplp); 241*22798Smckusick } 242*22798Smckusick } 243*22798Smckusick free( (charptr) vp); 244*22798Smckusick } 245*22798Smckusick } 246*22798Smckusick free ( (charptr) bb); 247*22798Smckusick } 248*22798Smckusick firstblock = lastblock = NULL; 249*22798Smckusick } 250*22798Smckusick 251*22798Smckusick 252*22798Smckusick /* structure for maintaining records on copy statements */ 253*22798Smckusick 254*22798Smckusick typedef struct Subrec { 255*22798Smckusick Addrp lmem; 256*22798Smckusick Addrp rmem; 257*22798Smckusick int sets; 258*22798Smckusick } *Subrecp; 259*22798Smckusick 260*22798Smckusick 261*22798Smckusick LOCAL chainp sublist; /* list of copy statements */ 262*22798Smckusick LOCAL int prop1count; /* count of number of temporaries eliminated */ 263*22798Smckusick LOCAL int prop2count; /* count of number of uses of temporaries replaced */ 264*22798Smckusick 265*22798Smckusick expptr rmcommaop(); 266*22798Smckusick Addrp subfor(); 267*22798Smckusick 268*22798Smckusick 269*22798Smckusick 270*22798Smckusick /* 271*22798Smckusick * eliminates copy statements of the form T1 = T2 from the intermediate 272*22798Smckusick * code, where T1 and T2 are temporary variables which are each 273*22798Smckusick * set only once; eliminates the copy statement and replaces each 274*22798Smckusick * use of T1 by T2 (T1 is therefore totally eliminated). 275*22798Smckusick */ 276*22798Smckusick 277*22798Smckusick LOCAL copyprop () 278*22798Smckusick 279*22798Smckusick { 280*22798Smckusick Slotp sl,nextsl; 281*22798Smckusick expptr expr; 282*22798Smckusick Tempp lp,rp; 283*22798Smckusick 284*22798Smckusick for (sl = firstslot; sl; sl = sl->next) 285*22798Smckusick sl->expr = rmcommaop (sl->expr,sl); 286*22798Smckusick 287*22798Smckusick prop1count = prop2count = 0; 288*22798Smckusick findcopies (); 289*22798Smckusick 290*22798Smckusick for (sl = firstslot; sl; sl = nextsl) 291*22798Smckusick { 292*22798Smckusick nextsl = sl->next; 293*22798Smckusick expr = sl->expr; 294*22798Smckusick 295*22798Smckusick if ((sl->type == SKFRTEMP) && subfor (expr)) 296*22798Smckusick { 297*22798Smckusick delslot (sl); 298*22798Smckusick expr = ENULL; 299*22798Smckusick } 300*22798Smckusick else if (expr && expr->tag == TEXPR && 301*22798Smckusick expr->exprblock.opcode == OPASSIGN) 302*22798Smckusick { 303*22798Smckusick lp = (Tempp) expr->exprblock.leftp; 304*22798Smckusick rp = (Tempp) expr->exprblock.rightp; 305*22798Smckusick if (lp->tag == TTEMP && rp->tag == TTEMP) 306*22798Smckusick if (subfor(lp->memalloc) == rp->memalloc 307*22798Smckusick && !subfor (rp->memalloc)) 308*22798Smckusick { 309*22798Smckusick frexpr (expr); 310*22798Smckusick expr = sl->expr = ENULL; 311*22798Smckusick prop1count++; 312*22798Smckusick } 313*22798Smckusick } 314*22798Smckusick 315*22798Smckusick propagate (expr); 316*22798Smckusick } 317*22798Smckusick 318*22798Smckusick if (debugflag[0]) 319*22798Smckusick fprintf (diagfile, 320*22798Smckusick "%d temporarie%s replaced by copy propagation (%d use%s)\n", 321*22798Smckusick prop1count,(prop1count==1 ? "" : "s"), 322*22798Smckusick prop2count,(prop2count==1 ? "" : "s") ); 323*22798Smckusick } 324*22798Smckusick 325*22798Smckusick 326*22798Smckusick 327*22798Smckusick /* 328*22798Smckusick * finds copy statements and enters information in table 329*22798Smckusick */ 330*22798Smckusick 331*22798Smckusick LOCAL findcopies () 332*22798Smckusick 333*22798Smckusick { 334*22798Smckusick Slotp sl; 335*22798Smckusick expptr expr; 336*22798Smckusick chainp cp; 337*22798Smckusick 338*22798Smckusick for (sl = firstslot; sl; sl = sl->next) 339*22798Smckusick { 340*22798Smckusick expr = sl->expr; 341*22798Smckusick if (expr) switch (expr->tag) 342*22798Smckusick { 343*22798Smckusick case TEXPR: 344*22798Smckusick ckexpr (expr); 345*22798Smckusick break; 346*22798Smckusick 347*22798Smckusick case TLIST: 348*22798Smckusick for (cp = expr->listblock.listp; cp; cp = cp->nextp) 349*22798Smckusick { 350*22798Smckusick expr = (expptr) cp->datap; 351*22798Smckusick ckexpr (expr); 352*22798Smckusick } 353*22798Smckusick break; 354*22798Smckusick 355*22798Smckusick default: 356*22798Smckusick break; 357*22798Smckusick } 358*22798Smckusick } 359*22798Smckusick } 360*22798Smckusick 361*22798Smckusick 362*22798Smckusick 363*22798Smckusick /* 364*22798Smckusick * checks an individual expression 365*22798Smckusick */ 366*22798Smckusick 367*22798Smckusick ckexpr (expr) 368*22798Smckusick expptr expr; 369*22798Smckusick 370*22798Smckusick { 371*22798Smckusick Tempp lp,rp; 372*22798Smckusick int oc = expr->exprblock.opcode; 373*22798Smckusick 374*22798Smckusick if (oc == OPASSIGN || oc == OPPLUSEQ || oc == OPSTAREQ) 375*22798Smckusick { 376*22798Smckusick lp = (Tempp) expr->exprblock.leftp; 377*22798Smckusick rp = (Tempp) expr->exprblock.rightp; 378*22798Smckusick if (lp->tag == TTEMP) 379*22798Smckusick if (rp->tag == TTEMP && oc == OPASSIGN) 380*22798Smckusick enter (lp->memalloc, rp->memalloc); 381*22798Smckusick else 382*22798Smckusick enter (lp->memalloc, ENULL); 383*22798Smckusick } 384*22798Smckusick } 385*22798Smckusick 386*22798Smckusick 387*22798Smckusick 388*22798Smckusick /* 389*22798Smckusick * Enters the given memalloc values in the table (or update if they 390*22798Smckusick * are already there), for the assignment statement m1 = m2. 391*22798Smckusick * If m2 is NULL, this indicates that the assignment is not a copy 392*22798Smckusick * statement. 393*22798Smckusick */ 394*22798Smckusick 395*22798Smckusick LOCAL enter (m1,m2) 396*22798Smckusick Addrp m1,m2; 397*22798Smckusick 398*22798Smckusick { 399*22798Smckusick chainp cp; 400*22798Smckusick Subrecp old,new; 401*22798Smckusick 402*22798Smckusick for (cp = sublist; cp; cp = cp->nextp) 403*22798Smckusick { 404*22798Smckusick old = (Subrecp) cp->datap; 405*22798Smckusick if (old->lmem == m1) 406*22798Smckusick { 407*22798Smckusick old->sets++; 408*22798Smckusick return; 409*22798Smckusick } 410*22798Smckusick } 411*22798Smckusick 412*22798Smckusick new = ALLOC (Subrec); 413*22798Smckusick new->lmem = m1; 414*22798Smckusick new->rmem = m2; 415*22798Smckusick new->sets = 1; 416*22798Smckusick sublist = mkchain (new, sublist); 417*22798Smckusick } 418*22798Smckusick 419*22798Smckusick 420*22798Smckusick 421*22798Smckusick /* 422*22798Smckusick * looks for record for the given memalloc value 423*22798Smckusick */ 424*22798Smckusick 425*22798Smckusick LOCAL Subrecp lookup (mem) 426*22798Smckusick Addrp mem; 427*22798Smckusick 428*22798Smckusick { 429*22798Smckusick chainp cp; 430*22798Smckusick Subrecp rec; 431*22798Smckusick 432*22798Smckusick for (cp = sublist; cp; cp = cp->nextp) 433*22798Smckusick { 434*22798Smckusick rec = (Subrecp) cp->datap; 435*22798Smckusick if (rec->lmem == mem) 436*22798Smckusick return rec; 437*22798Smckusick } 438*22798Smckusick 439*22798Smckusick return NULL; 440*22798Smckusick } 441*22798Smckusick 442*22798Smckusick 443*22798Smckusick 444*22798Smckusick /* 445*22798Smckusick * checks to see if there is a substitute for given memalloc value 446*22798Smckusick */ 447*22798Smckusick 448*22798Smckusick LOCAL Addrp subfor (mem) 449*22798Smckusick Addrp mem; 450*22798Smckusick 451*22798Smckusick { 452*22798Smckusick Subrecp rec,rec2; 453*22798Smckusick Addrp sub; 454*22798Smckusick 455*22798Smckusick rec = lookup (mem); 456*22798Smckusick if (rec && rec->sets == 1) 457*22798Smckusick { 458*22798Smckusick sub = rec->rmem; 459*22798Smckusick rec2 = lookup(sub); 460*22798Smckusick if (rec2 && rec2->sets == 1) 461*22798Smckusick return sub; 462*22798Smckusick } 463*22798Smckusick 464*22798Smckusick return NULL; 465*22798Smckusick } 466*22798Smckusick 467*22798Smckusick 468*22798Smckusick 469*22798Smckusick /* 470*22798Smckusick * actually propagates the information 471*22798Smckusick */ 472*22798Smckusick 473*22798Smckusick LOCAL propagate (expr) 474*22798Smckusick expptr expr; 475*22798Smckusick 476*22798Smckusick { 477*22798Smckusick chainp t; 478*22798Smckusick Addrp new; 479*22798Smckusick 480*22798Smckusick if (! expr) return; 481*22798Smckusick 482*22798Smckusick switch (expr->tag) 483*22798Smckusick { 484*22798Smckusick case TEXPR: 485*22798Smckusick propagate (expr->exprblock.leftp); 486*22798Smckusick propagate (expr->exprblock.rightp); 487*22798Smckusick break; 488*22798Smckusick 489*22798Smckusick case TADDR: 490*22798Smckusick propagate (expr->addrblock.vleng); 491*22798Smckusick propagate (expr->addrblock.memoffset); 492*22798Smckusick break; 493*22798Smckusick 494*22798Smckusick case TLIST: 495*22798Smckusick for (t = expr->listblock.listp; t; t = t->nextp) 496*22798Smckusick propagate (t->datap); 497*22798Smckusick break; 498*22798Smckusick 499*22798Smckusick case TTEMP: 500*22798Smckusick new = subfor (expr->tempblock.memalloc); 501*22798Smckusick if (new) 502*22798Smckusick { 503*22798Smckusick expr->tempblock.memalloc = new; 504*22798Smckusick prop2count++; 505*22798Smckusick } 506*22798Smckusick break; 507*22798Smckusick 508*22798Smckusick default: 509*22798Smckusick break; 510*22798Smckusick } 511*22798Smckusick } 512*22798Smckusick 513*22798Smckusick 514*22798Smckusick 515*22798Smckusick /* 516*22798Smckusick * allocates ADDR blocks for each TEMP in the expression 517*22798Smckusick */ 518*22798Smckusick 519*22798Smckusick LOCAL expptr tempalloc (expr) 520*22798Smckusick expptr expr; 521*22798Smckusick 522*22798Smckusick { 523*22798Smckusick chainp t; 524*22798Smckusick 525*22798Smckusick if (! expr) 526*22798Smckusick return NULL; 527*22798Smckusick 528*22798Smckusick switch (expr->tag) 529*22798Smckusick { 530*22798Smckusick case TEXPR: 531*22798Smckusick expr->exprblock.leftp = tempalloc (expr->exprblock.leftp); 532*22798Smckusick expr->exprblock.rightp = tempalloc (expr->exprblock.rightp); 533*22798Smckusick break; 534*22798Smckusick 535*22798Smckusick case TADDR: 536*22798Smckusick expr->addrblock.vleng = tempalloc (expr->addrblock.vleng); 537*22798Smckusick expr->addrblock.memoffset = tempalloc (expr->addrblock.memoffset); 538*22798Smckusick break; 539*22798Smckusick 540*22798Smckusick case TLIST: 541*22798Smckusick for (t = expr->listblock.listp; t; t = t->nextp) 542*22798Smckusick t->datap = (tagptr) tempalloc (t->datap); 543*22798Smckusick break; 544*22798Smckusick 545*22798Smckusick case TTEMP: 546*22798Smckusick return (expptr) cpexpr (altmpn (expr)); 547*22798Smckusick break; 548*22798Smckusick 549*22798Smckusick default: 550*22798Smckusick break; 551*22798Smckusick } 552*22798Smckusick return expr; 553*22798Smckusick } 554*22798Smckusick 555*22798Smckusick 556*22798Smckusick /********************* debugging routines *********************/ 557*22798Smckusick 558*22798Smckusick 559*22798Smckusick 560*22798Smckusick Announce (s,q) 561*22798Smckusick char *s; 562*22798Smckusick expptr q; 563*22798Smckusick 564*22798Smckusick { 565*22798Smckusick fprintf (diagfile,"\nAn expression [%s]----->\n",s); 566*22798Smckusick showexpr(q,0); 567*22798Smckusick fprintf (diagfile,"\n-------------end of expr--------------\n"); 568*22798Smckusick } 569*22798Smckusick 570*22798Smckusick 571*22798Smckusick 572*22798Smckusick /* 573*22798Smckusick * dump the basic block buffer, including expressions, mnemonically 574*22798Smckusick */ 575*22798Smckusick 576*22798Smckusick showbuffer () 577*22798Smckusick 578*22798Smckusick { 579*22798Smckusick Slotp sl; 580*22798Smckusick Bblockp bb; 581*22798Smckusick int i; 582*22798Smckusick 583*22798Smckusick fprintf (diagfile,"Basic blocks with first and last slots ----------\n"); 584*22798Smckusick for (i=1, bb = firstblock; bb; i++, bb = bb->next) 585*22798Smckusick fprintf (diagfile,"%2d. %d %d\n",i,bb->first,bb->last); 586*22798Smckusick fprintf (diagfile,"\n"); 587*22798Smckusick 588*22798Smckusick fprintf (diagfile,"Slots and expressions ----------\n"); 589*22798Smckusick 590*22798Smckusick fprintf (diagfile,"tag pointer vtype vclass vstg vleng\n"); 591*22798Smckusick fprintf (diagfile," ADDR memno memoffset istemp ntempelt varleng\n"); 592*22798Smckusick fprintf (diagfile," TEMP memalloc istemp ntempelt varleng\n"); 593*22798Smckusick fprintf (diagfile," EXPR opcode leftp rightp\n"); 594*22798Smckusick fprintf (diagfile," LIST type listp\n"); 595*22798Smckusick fprintf (diagfile,"\n"); 596*22798Smckusick 597*22798Smckusick for (i=1, sl = firstslot; sl; i++, sl = sl->next) 598*22798Smckusick { 599*22798Smckusick fprintf (diagfile,"%2d. ",i); 600*22798Smckusick showslt (sl); 601*22798Smckusick } 602*22798Smckusick fprintf (diagfile,"---------- End of showbuffer ----------\n"); 603*22798Smckusick } 604*22798Smckusick 605*22798Smckusick 606*22798Smckusick 607*22798Smckusick /* 608*22798Smckusick * dumps a single slot in the code buffer 609*22798Smckusick */ 610*22798Smckusick 611*22798Smckusick LOCAL charptr Zslot[] = {"NULL", 612*22798Smckusick "IFN","GOTO","LABEL","EQ","CALL","CMGOTO","STOP","DOHEAD", 613*22798Smckusick "ENDDO","ARIF","RETURN","ASGOTO","PAUSE","ASSIGN","IOIFN","FRTEMP"}; 614*22798Smckusick 615*22798Smckusick 616*22798Smckusick 617*22798Smckusick showslt (sl) 618*22798Smckusick Slotp sl; 619*22798Smckusick 620*22798Smckusick { 621*22798Smckusick fprintf (diagfile,"(%2d) %d %s %d\n", 622*22798Smckusick sl->lineno,sl,Zslot[sl->type],sl->label); 623*22798Smckusick showexpr (sl->expr,0); 624*22798Smckusick fprintf (diagfile,"\n"); 625*22798Smckusick } 626*22798Smckusick 627*22798Smckusick 628*22798Smckusick 629*22798Smckusick showslottype (type) 630*22798Smckusick int type; 631*22798Smckusick 632*22798Smckusick { 633*22798Smckusick fprintf (diagfile,"%s\n",Zslot[type]); 634*22798Smckusick } 635*22798Smckusick 636*22798Smckusick 637*22798Smckusick 638*22798Smckusick /* 639*22798Smckusick * displays the given expression at the given indentation, showing 640*22798Smckusick * its subexpressions at further indentations 641*22798Smckusick */ 642*22798Smckusick 643*22798Smckusick LOCAL charptr Ztag[] = {"----", 644*22798Smckusick "NAME","CONST","EXPR","ADDR","TEMP","PRIM","LIST","IMPLDO","ERROR"}; 645*22798Smckusick LOCAL charptr Zstg[] = {"unk", 646*22798Smckusick "ARG","AUTO","BSS","INIT","CONST","EXT","INTR","STFUNCT", 647*22798Smckusick "COMMON","EQUIV","REG","LENG","NULL","PREG"}; 648*22798Smckusick LOCAL charptr Zclass[] = {"unk", 649*22798Smckusick "PARAM","VAR","ENTRY","MAIN","BLOCK","PROC","NAMELIST"}; 650*22798Smckusick LOCAL charptr Zop[] = {"----", 651*22798Smckusick "PLUS","MINUS","STAR","SLASH","POWER","NEG","OR","AND","EQV", 652*22798Smckusick "NEQV","NOT","CONCAT","LT","EQ","GT","LE","NE","GE","CALL", 653*22798Smckusick "CCALL","ASSIGN","PLUSEQ","STAREQ","CONV","LSHIFT","MOD", 654*22798Smckusick "COMMA","QUEST","COLON","ABS","MIN","MAX","ADDR","INDIRECT", 655*22798Smckusick "BITOR","BITAND","BITXOR","BITNOT","RSHIFT","PAREN"}; 656*22798Smckusick LOCAL charptr Ztype[] = {"unk", 657*22798Smckusick "ADDR","SHORT","LONG","REAL","DREAL","COMPLEX","DCOMPLEX", 658*22798Smckusick "LOGICAL","CHAR","SUBR","ERROR"}; 659*22798Smckusick 660*22798Smckusick 661*22798Smckusick showexpr(p,indent) 662*22798Smckusick tagptr p; 663*22798Smckusick int indent; 664*22798Smckusick 665*22798Smckusick { 666*22798Smckusick int i; 667*22798Smckusick int type; 668*22798Smckusick chainp q; 669*22798Smckusick 670*22798Smckusick #define PRHEAD(q) fprintf(diagfile,"%s %d %s %s %s %d", \ 671*22798Smckusick Ztag[q->tag], q, Ztype[q->headblock.vtype], \ 672*22798Smckusick Zclass[q->headblock.vclass], Zstg[q->headblock.vstg], \ 673*22798Smckusick q->headblock.vleng); 674*22798Smckusick #define SHOWEXPR(p) showexpr(p,indent+2) 675*22798Smckusick 676*22798Smckusick 677*22798Smckusick 678*22798Smckusick if(p == NULL) 679*22798Smckusick return; 680*22798Smckusick 681*22798Smckusick for (i=0; i<indent; i++) 682*22798Smckusick putc(' ',diagfile); 683*22798Smckusick 684*22798Smckusick switch(p->tag) 685*22798Smckusick { 686*22798Smckusick case TCONST: 687*22798Smckusick PRHEAD(p); 688*22798Smckusick 689*22798Smckusick type=p->constblock.vtype; 690*22798Smckusick if (ISCHAR(p)) 691*22798Smckusick { 692*22798Smckusick fprintf(diagfile," ISCHAR ccp= %d\n", 693*22798Smckusick p->constblock.const.ccp); 694*22798Smckusick SHOWEXPR(p->constblock.vleng); 695*22798Smckusick } 696*22798Smckusick else if( ISINT(type) ) 697*22798Smckusick fprintf(diagfile," ci= %d\n",p->constblock.const.ci); 698*22798Smckusick else if( ISREAL(type) ) 699*22798Smckusick fprintf(diagfile," cd[0]= %e\n",p->constblock.const.cd[0]); 700*22798Smckusick else fprintf(diagfile," cd[0]= %e cd[1]= %e\n", 701*22798Smckusick p->constblock.const.cd[0], 702*22798Smckusick p->constblock.const.cd[1] ); 703*22798Smckusick break; 704*22798Smckusick 705*22798Smckusick case TADDR: 706*22798Smckusick PRHEAD(p); 707*22798Smckusick fprintf(diagfile, 708*22798Smckusick " memno= %d %d %d %d %d\n", 709*22798Smckusick p->addrblock.memno,p->addrblock.memoffset,p->addrblock.istemp, 710*22798Smckusick p->addrblock.ntempelt,p->addrblock.varleng); 711*22798Smckusick SHOWEXPR(p->addrblock.vleng); 712*22798Smckusick SHOWEXPR(p->addrblock.memoffset); 713*22798Smckusick break; 714*22798Smckusick 715*22798Smckusick case TTEMP: 716*22798Smckusick fprintf(diagfile,"%s %d %s %s %d", 717*22798Smckusick Ztag[p->tag], p, Ztype[p->headblock.vtype], 718*22798Smckusick Zclass[p->headblock.vclass], 719*22798Smckusick p->headblock.vleng); 720*22798Smckusick fprintf(diagfile, 721*22798Smckusick " memalloc= %d %d %d %d\n", 722*22798Smckusick p->tempblock.memalloc,p->tempblock.istemp, 723*22798Smckusick p->tempblock.ntempelt,p->tempblock.varleng); 724*22798Smckusick SHOWEXPR(p->tempblock.vleng); 725*22798Smckusick SHOWEXPR(p->tempblock.memalloc); 726*22798Smckusick break; 727*22798Smckusick 728*22798Smckusick case TERROR: 729*22798Smckusick fprintf(diagfile,"ERROR %d\n",p); 730*22798Smckusick break; 731*22798Smckusick 732*22798Smckusick case TNAME: 733*22798Smckusick fprintf(diagfile,"NAME %d\n",p); 734*22798Smckusick return; 735*22798Smckusick 736*22798Smckusick case TPRIM: 737*22798Smckusick fprintf(diagfile,"PRIM %d --- not implemented\n",p); 738*22798Smckusick break; 739*22798Smckusick 740*22798Smckusick case TEXPR: 741*22798Smckusick PRHEAD(p); 742*22798Smckusick fprintf(diagfile," opcode= %s %d %d\n", 743*22798Smckusick Zop[p->exprblock.opcode],p->exprblock.leftp, 744*22798Smckusick p->exprblock.rightp); 745*22798Smckusick SHOWEXPR(p->exprblock.leftp); 746*22798Smckusick if(p->exprblock.rightp) 747*22798Smckusick SHOWEXPR(p->exprblock.rightp); 748*22798Smckusick break; 749*22798Smckusick 750*22798Smckusick case TLIST: 751*22798Smckusick fprintf(diagfile,"LIST %d %s %d\n",p, 752*22798Smckusick Ztype[p->listblock.vtype],p->listblock.listp); 753*22798Smckusick for(q= p->listblock.listp ; q ; q = q->nextp) 754*22798Smckusick SHOWEXPR(q->datap); 755*22798Smckusick for (i=0; i<indent; i++) 756*22798Smckusick putc (' ',diagfile); 757*22798Smckusick fprintf(diagfile,"END LIST %d\n",p); 758*22798Smckusick break; 759*22798Smckusick 760*22798Smckusick default: 761*22798Smckusick fprintf(diagfile,"showexpr BAD TAG= %d at %d \n",p->tag,p); 762*22798Smckusick } 763*22798Smckusick } 764*22798Smckusick 765*22798Smckusick 766*22798Smckusick 767*22798Smckusick selective()/************************************/ 768*22798Smckusick { 769*22798Smckusick int i; 770*22798Smckusick Slotp sl; 771*22798Smckusick 772*22798Smckusick i=0; 773*22798Smckusick fprintf (stderr,"SELECTIVE OUTPUT\n"); 774*22798Smckusick for (sl=firstslot;sl;sl=sl->next) 775*22798Smckusick { 776*22798Smckusick i++; 777*22798Smckusick if (i>=176 && i<184) 778*22798Smckusick { 779*22798Smckusick fprintf (stderr,"%d. ",i); 780*22798Smckusick showslt(sl); 781*22798Smckusick } 782*22798Smckusick } 783*22798Smckusick } 784*22798Smckusick 785*22798Smckusick 786*22798Smckusick 787*22798Smckusick 788*22798Smckusick LOCAL containscall(p) 789*22798Smckusick expptr p; 790*22798Smckusick { 791*22798Smckusick chainp cp; 792*22798Smckusick 793*22798Smckusick if (p == NULL) 794*22798Smckusick return NO; 795*22798Smckusick 796*22798Smckusick switch (p->tag) 797*22798Smckusick { 798*22798Smckusick case TADDR: 799*22798Smckusick if (containscall(p->addrblock.vleng) 800*22798Smckusick || containscall(p->addrblock.memoffset)) 801*22798Smckusick return YES; 802*22798Smckusick else 803*22798Smckusick return NO; 804*22798Smckusick 805*22798Smckusick case TCONST: 806*22798Smckusick return NO; 807*22798Smckusick 808*22798Smckusick case TERROR: 809*22798Smckusick return NO; 810*22798Smckusick 811*22798Smckusick case TEXPR: 812*22798Smckusick if (p->exprblock.opcode == OPCALL || 813*22798Smckusick p->exprblock.opcode == OPCCALL) 814*22798Smckusick return YES; 815*22798Smckusick if (containscall(p->exprblock.vleng) || 816*22798Smckusick containscall(p->exprblock.leftp) || 817*22798Smckusick containscall(p->exprblock.rightp)) 818*22798Smckusick return YES; 819*22798Smckusick else 820*22798Smckusick return NO; 821*22798Smckusick 822*22798Smckusick case TLIST: 823*22798Smckusick cp = p->listblock.listp; 824*22798Smckusick while (cp) 825*22798Smckusick { 826*22798Smckusick if (containscall(cp->datap)) 827*22798Smckusick return YES; 828*22798Smckusick cp = cp->nextp; 829*22798Smckusick } 830*22798Smckusick return NO; 831*22798Smckusick 832*22798Smckusick default: 833*22798Smckusick return YES; 834*22798Smckusick } 835*22798Smckusick } 836