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

Defined functions

Announce defined in line 566; never used
ckexpr defined in line 372; used 2 times
clearbb defined in line 204; used 1 times
containscall defined in line 794; used 7 times
copyprop defined in line 282; used 1 times
  • in line 75
enter defined in line 400; used 2 times
findcopies defined in line 336; used 1 times
formbblock defined in line 134; used 1 times
  • in line 69
lookup defined in line 430; used 2 times
newblock defined in line 104; used 5 times
optimize defined in line 57; used 1 times
propagate defined in line 478; used 6 times
selective defined in line 773; never used
showexpr defined in line 667; used 4 times
showslottype defined in line 635; used 1 times
showslt defined in line 623; used 2 times
subfor defined in line 453; used 5 times
tempalloc defined in line 524; used 8 times

Defined variables

firstblock defined in line 51; used 4 times
lastblock defined in line 52; used 6 times
prop1count defined in line 267; used 4 times
prop2count defined in line 268; used 4 times
sccsid defined in line 8; never used
sublist defined in line 266; used 4 times

Defined struct's

Subrec defined in line 259; never used

Defined typedef's

Subrecp defined in line 263; used 6 times

Defined macros

PRHEAD defined in line 676; used 3 times
SHOWEXPR defined in line 680; used 8 times
Last modified: 1986-03-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2793
Valid CSS Valid XHTML 1.0 Strict