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