Annotation of 42BSD/usr.bin/f77/src/f77pass1/optloop.c, revision 1.1.1.1

1.1       root        1: #include "defs.h"
                      2: #include "optim.h"
                      3: 
                      4: 
                      5: #define SCFREE   0
                      6: #define SCSAFE   1
                      7: 
                      8: 
                      9: 
                     10: typedef
                     11:   struct varblock
                     12:     {
                     13:       struct varblock *next;
                     14:       field vstg;
                     15:       int memno;       /* holds memalloc for TTEMP */
                     16:       short sets;
                     17:       short uses;
                     18:       field setfirst;
                     19:     } VARBLOCK;
                     20: 
                     21: typedef VARBLOCK *Varp;
                     22: 
                     23: #define TABLESIZE 59
                     24: 
                     25: LOCAL Varp table[TABLESIZE];
                     26: 
                     27: 
                     28: 
                     29: LOCAL Varp mkbucket(vstg,memno)
                     30: field vstg;
                     31: int memno;
                     32: 
                     33: {
                     34:   Varp q;
                     35: 
                     36:   q = ALLOC(varblock);
                     37:   q->vstg = vstg;
                     38:   q->memno = memno;
                     39:   return q;
                     40: }
                     41: 
                     42: 
                     43: 
                     44: LOCAL Varp lookup(p)
                     45: tagptr p;
                     46: 
                     47: {
                     48: int vstg, memno;
                     49: int key;
                     50: Varp q, r;
                     51: 
                     52: switch (p->tag)
                     53:        {
                     54:        case TTEMP:
                     55:                vstg = 0;
                     56:                memno = (int) p->tempblock.memalloc;
                     57:                break;
                     58: 
                     59:        case TADDR:
                     60:                vstg = p->addrblock.vstg;
                     61:                memno = p->addrblock.memno;
                     62:                break;
                     63: 
                     64:        default:
                     65:                badtag ("lookup",p->tag);
                     66:        }
                     67: key = memno % TABLESIZE;
                     68: q = table[key];
                     69: 
                     70: if (q)
                     71:        {
                     72:        for (; q; r = q, q = q->next)
                     73:                if ((q->vstg == vstg) && (q->memno == memno))
                     74:                        return q;
                     75:        return r->next = mkbucket(vstg,memno);
                     76:        }
                     77: else
                     78:        return table[key] = mkbucket(vstg,memno);
                     79: }
                     80: 
                     81: 
                     82: 
                     83: LOCAL freetable()
                     84: 
                     85: {
                     86:   int i;
                     87:   Varp p, q;
                     88: 
                     89:   for (i = 0; i < TABLESIZE; i++)
                     90:     if (table[i])
                     91:       {
                     92:        p = table[i];
                     93:        table[i] = NULL;
                     94: 
                     95:        while (p)
                     96:          {
                     97:            q = p->next;
                     98:            free((char *) p);
                     99:            p = q;
                    100:          }
                    101:       }
                    102: }
                    103: 
                    104: 
                    105: 
                    106: Slotp newcode;
                    107: Slotp dohead, doend;
                    108: LOCAL Slotp first, last;
                    109: LOCAL commonset;
                    110: LOCAL int comocount;   /* count of number of code motions done */
                    111: 
                    112: 
                    113: optloops()
                    114: 
                    115: {
                    116: int    match;
                    117: Slotp  nextslot;
                    118: Slotp  sl1,sl2;
                    119: Slotp  lastlabslot;
                    120: int    lab;
                    121: 
                    122: if (! optimflag) return;
                    123: if (debugflag[6]) return;
                    124: 
                    125: lastlabslot = NULL;
                    126: comocount = 0;
                    127: for (sl1 = firstslot; sl1; sl1 = nextslot)
                    128:        {
                    129:        nextslot = sl1->next;
                    130:        switch (sl1->type)
                    131:            {
                    132:            case SKLABEL:
                    133:                lastlabslot = sl1;
                    134:                break;
                    135: 
                    136:            case SKGOTO:
                    137:                if (lastlabslot && sl1->label == lastlabslot->label)
                    138:                        {
                    139:                        lab = newlabel ();
                    140:                        first = optinsert (SKLABEL,0,lab,0,lastlabslot->next);
                    141:                        last = sl1;
                    142:                        last->label = lab;
                    143:                        optloop ();
                    144:                        }
                    145:                break;
                    146: 
                    147:            case SKDOHEAD:
                    148:                match = 0;
                    149:                for (sl2 = sl1; sl2; sl2 = sl2->next)
                    150:                        {
                    151:                        if (sl2->type == SKDOHEAD) match++;
                    152:                        else if (sl2->type == SKENDDO) match--;
                    153:                        if (match == 0) break;
                    154:                        }
                    155:                if (sl2)
                    156:                        last = sl2;
                    157:                else
                    158:                        fatal ("unmatched do in code buffer");
                    159:                if (sl2->type != SKENDDO)
                    160:                        fatal ("internal error in optloops");
                    161: 
                    162:                /*  last now points to the SKENDDO slot; the SKNULL slot
                    163:                 *  is reached through last->nullslot
                    164:                 */
                    165:                last = (Slotp) last->nullslot;
                    166: 
                    167:                first = sl1;
                    168: 
                    169:                optloop ();
                    170:                break;
                    171: 
                    172:            default:
                    173:                break;
                    174:            }
                    175:        }
                    176: 
                    177: if (debugflag[0])
                    178:        fprintf (diagfile,"%d code motion%s performed\n",comocount,
                    179:                (comocount==1 ? "" : "s") );
                    180: return;
                    181: }
                    182: 
                    183: 
                    184: 
                    185: optloop()
                    186: 
                    187: {
                    188: newcode = NULL;
                    189: 
                    190: modify();
                    191: 
                    192: return;
                    193: }
                    194: 
                    195: 
                    196: LOCAL modify()
                    197: 
                    198: {
                    199:   Slotp sp;
                    200:   int s;
                    201: 
                    202:   scanvars();
                    203: 
                    204:   for (sp = first; sp != last->next; sp = sp->next)
                    205:     switch (sp->type)
                    206:       {
                    207:       case SKEQ:
                    208:        s = anex(sp->expr);
                    209:        if (s == SCSAFE)
                    210:          removesafe (&sp->expr);
                    211:        break;
                    212: 
                    213:       case SKARIF:
                    214:       case SKASGOTO:
                    215:       case SKCALL:
                    216:       case SKCMGOTO:
                    217:       case SKIFN:
                    218:       case SKSTOP:
                    219:       case SKRETURN:
                    220:       case SKPAUSE:
                    221:       case SKIOIFN:
                    222:        s = anex(sp->expr);
                    223:        if (s == SCSAFE)
                    224:          removesafe(&sp->expr);
                    225:        break;
                    226: 
                    227:       default:
                    228:        break;
                    229:       }
                    230: 
                    231:   freetable();
                    232:   return;
                    233: }
                    234: 
                    235: 
                    236: LOCAL scanvars()
                    237: 
                    238: {
                    239:   Slotp sp;
                    240:   Varp varinfo;
                    241:   int i;
                    242:   Varp p;
                    243: 
                    244:   commonset = NO;
                    245: 
                    246:   for (sp = first; sp != last->next; sp = sp->next)
                    247:     {
                    248:       switch (sp->type)
                    249:        {
                    250:        case SKARIF:
                    251:        case SKASGOTO:
                    252:        case SKCALL:
                    253:        case SKCMGOTO:
                    254:        case SKIFN:
                    255:        case SKSTOP:
                    256:        case SKRETURN:
                    257:        case SKPAUSE:
                    258:        case SKIOIFN:
                    259:        case SKEQ:
                    260:          setsuses(sp->expr);
                    261:          break;
                    262: 
                    263:        default:
                    264:          break;
                    265:        }
                    266:     }
                    267: 
                    268:   if (commonset)
                    269:     for (i = 0; i < TABLESIZE; i++)
                    270:       for (p = table[i]; p; p = p->next)
                    271:        if (p->vstg == STGCOMMON)
                    272:          {
                    273:            p->sets++;
                    274:            p->setfirst = NO;
                    275:          }
                    276: }
                    277: 
                    278: 
                    279: LOCAL setsuses(p)
                    280: expptr p;
                    281: 
                    282: {
                    283:   Addrp lhs;
                    284:   Varp varinfo;
                    285:   chainp args;
                    286: 
                    287:   if (!p) return;
                    288: 
                    289:   switch (p->tag)
                    290:     {
                    291:     case TEXPR:
                    292:       switch (p->exprblock.opcode)
                    293:        {
                    294:        default:
                    295:          setsuses(p->exprblock.leftp);
                    296:          setsuses(p->exprblock.rightp);
                    297:          setsuses(p->exprblock.vleng);
                    298:          break;
                    299: 
                    300:        case OPASSIGN:
                    301:          switch (p->exprblock.leftp->tag)
                    302:            {
                    303:            case TTEMP:
                    304:              lhs = (Addrp) p->exprblock.leftp;
                    305:              goto taddr;
                    306: 
                    307:            case TADDR:
                    308:              lhs = (Addrp) p->exprblock.leftp;
                    309:              setsuses(lhs->memoffset);
                    310:              setsuses(lhs->vleng);
                    311:            taddr:
                    312:              setsuses(p->exprblock.rightp);
                    313:              setsuses(p->exprblock.vleng);
                    314:              varinfo = lookup(lhs);
                    315:              varinfo->sets++;
                    316:               if (varinfo->uses == 0)
                    317:                varinfo->setfirst = YES;
                    318:              break;
                    319: 
                    320:            default:
                    321:              fatal("O6:  l-value expected");
                    322:            }
                    323:          break;
                    324: 
                    325:        case OPSTAREQ:
                    326:        case OPPLUSEQ:
                    327:          switch (p->exprblock.leftp->tag)
                    328:            {
                    329:            case TADDR:
                    330:              lhs = (Addrp) p->exprblock.leftp;
                    331:              break;
                    332:            case TTEMP:
                    333:              lhs = (Addrp) p->exprblock.leftp;
                    334:              break;
                    335:            default:
                    336:              fatal("O7:  l-value expected");
                    337:            }
                    338:          setsuses(p->exprblock.leftp);
                    339:          setsuses(p->exprblock.rightp);
                    340:          setsuses(p->exprblock.vleng);
                    341:          varinfo = lookup(lhs);
                    342:          varinfo->sets++;
                    343:          break;
                    344: 
                    345:        case OPCALL:
                    346:          if (p->exprblock.leftp->tag != TADDR)
                    347:            fatal("O8:  subprogram expected");
                    348:          setsuses(p->exprblock.rightp);
                    349:          setsuses(p->exprblock.vleng);
                    350:          if (p->exprblock.leftp->addrblock.vstg != STGEXT) break;
                    351:          commonset = YES;
                    352:          if (p->exprblock.rightp == NULL) break;
                    353:          args = p->exprblock.rightp->listblock.listp;
                    354:          for (; args; args = args->nextp)
                    355:            if (args->datap->tag == TADDR)
                    356:              {
                    357:                lhs = (Addrp) args->datap;
                    358:                switch (lhs->vstg)
                    359:                  {
                    360:                  case STGARG:
                    361:                  case STGAUTO:
                    362:                  case STGBSS:
                    363:                  case STGINIT:
                    364:                  case STGCOMMON:
                    365:                  case STGEQUIV:
                    366:                  case STGREG:
                    367:                  case STGPREG:
                    368:                    varinfo = lookup(lhs);
                    369:                    varinfo->sets++;
                    370:                  }
                    371:              }
                    372:            else if (args->datap->tag == TTEMP)
                    373:              {
                    374:                lhs = (Addrp) args->datap;
                    375:                varinfo = lookup (lhs);
                    376:                varinfo->sets++;
                    377:              }
                    378:          break;
                    379:         }
                    380: 
                    381:       return;
                    382: 
                    383:     case TTEMP:
                    384:       varinfo = lookup((Addrp) p);
                    385:       varinfo->uses++;
                    386:       return;
                    387: 
                    388:     case TADDR:
                    389:       setsuses(p->addrblock.memoffset);
                    390:       setsuses(p->addrblock.vleng);
                    391:       varinfo = lookup((Addrp) p);
                    392:       varinfo->uses++;
                    393:       return;
                    394: 
                    395:     case TLIST:
                    396:       for (args = p->listblock.listp; args; args = args->nextp)
                    397:        setsuses(args->datap);
                    398: 
                    399:     case TCONST:
                    400:     case TERROR:
                    401:       return;
                    402: 
                    403:     default:
                    404:       fatal("O9:  bad tag value");
                    405:     }
                    406: }
                    407: 
                    408: 
                    409: LOCAL int anex(p)
                    410: expptr p;
                    411: 
                    412: {
                    413:   int s1, s2, s3;
                    414:   expptr q;
                    415:   Varp varinfo;
                    416:   chainp ch;
                    417:   int setfirst;
                    418:   expptr expr;
                    419: 
                    420: 
                    421:   if (p == ENULL)
                    422:     return SCSAFE;
                    423: 
                    424:   switch (p->tag)
                    425:     {
                    426:     case TCONST:
                    427:       return SCSAFE;
                    428: 
                    429:     case TLIST:
                    430:       for (ch = p->listblock.listp; ch; ch = ch->nextp)
                    431:        {
                    432:          s1 = anex (ch->datap);
                    433:          if (s1 == SCSAFE)
                    434:            removesafe (&ch->datap);
                    435:        }
                    436:       return SCFREE;
                    437: 
                    438:     case TEXPR:
                    439:       s1 = anex(p->exprblock.leftp);
                    440:       s2 = anex(p->exprblock.rightp);
                    441:       s3 = anex(p->exprblock.vleng);
                    442: 
                    443:       switch (p->exprblock.opcode)
                    444:        {
                    445:        case OPASSIGN:
                    446:          expr = p->exprblock.leftp;
                    447:          varinfo = lookup(expr);
                    448:          setfirst = varinfo->setfirst && (varinfo->sets == 1);
                    449:          if (expr->tag == TTEMP && setfirst &&
                    450:                s2 == SCSAFE && s3 == SCSAFE)
                    451:            {
                    452:              movefrtemp (expr);
                    453:              return SCSAFE;
                    454:            }
                    455:          else
                    456:            {
                    457:              if (s2 == SCSAFE) removesafe (&p->exprblock.rightp);
                    458:              if (s3 == SCSAFE) removesafe (&p->exprblock.vleng);
                    459:              return SCFREE;
                    460:            }
                    461: 
                    462:        case OPNEG:
                    463:        case OPNOT:
                    464:        case OPABS:
                    465:        case OPADDR:
                    466:        case OPBITNOT:
                    467:          if ((s2 == SCSAFE) && (s3 == SCSAFE))
                    468:            return s1;
                    469:          else
                    470:            return SCFREE;
                    471: 
                    472:        case OPCONV:
                    473:          if ((s2 != SCSAFE) || (s3 != SCSAFE))
                    474:            return SCFREE;
                    475: 
                    476:          if (ISINT(p->exprblock.vtype))
                    477:            return s1;
                    478:          if (ISINT(p->exprblock.leftp->headblock.vtype))
                    479:            return s1;
                    480: 
                    481:          return SCFREE;
                    482: 
                    483: 
                    484:        case OPSTAR:
                    485:          if (ISINT(p->exprblock.vtype))
                    486:            goto safeop;
                    487: 
                    488:          if (safefactor(p->exprblock.leftp) ||
                    489:              safefactor(p->exprblock.rightp))
                    490:            goto safeop;
                    491: 
                    492:          goto floatop;
                    493: 
                    494: 
                    495:        case OPPLUS:
                    496:        case OPMINUS:
                    497:          if (ISINT(p->exprblock.vtype))
                    498:            goto safeop;
                    499: 
                    500:        floatop:
                    501:          if (!(ISREAL(p->exprblock.vtype) || ISCOMPLEX(p->exprblock.vtype)))
                    502:            return SCFREE;
                    503: 
                    504:          switch (s1)
                    505:            {
                    506:            case SCSAFE:
                    507:              removesafe(&p->exprblock.leftp);
                    508:              if (s2 == SCSAFE)
                    509:                removesafe(&p->exprblock.leftp);
                    510:              return SCFREE;
                    511: 
                    512:            case SCFREE:
                    513:              if (s2 == SCSAFE)
                    514:                removesafe(&p->exprblock.rightp);
                    515:              return SCFREE;
                    516:            }
                    517: 
                    518:        case OPOR:
                    519:        case OPAND:
                    520:        case OPEQV:
                    521:        case OPNEQV:
                    522:        case OPLT:
                    523:        case OPEQ:
                    524:        case OPGT:
                    525:        case OPLE:
                    526:        case OPNE:
                    527:        case OPGE:
                    528:        case OPLSHIFT:
                    529:        case OPMIN:
                    530:        case OPMAX:
                    531:        case OPBITOR:
                    532:        case OPBITAND:
                    533:        case OPBITXOR:
                    534:        case OPRSHIFT:
                    535:        safeop:
                    536:          if ((p->exprblock.vleng != ENULL) && ( ! ISCONST(p->exprblock.vleng)))
                    537:            return SCFREE;
                    538: 
                    539:          switch (s1)
                    540:            {
                    541:            case SCSAFE:
                    542:                if (s2 == SCFREE) removesafe (&p->exprblock.leftp);
                    543:                return s2;
                    544: 
                    545:            case SCFREE:
                    546:                if (s2 == SCSAFE) removesafe (&p->exprblock.rightp);
                    547:                return SCFREE;
                    548:            }
                    549: 
                    550:        default:
                    551:          if (s1 == SCSAFE) removesafe(&p->exprblock.leftp);
                    552:          if (s2 == SCSAFE) removesafe(&p->exprblock.rightp);
                    553:          if (s3 == SCSAFE) removesafe(&p->exprblock.vleng);
                    554:          return SCFREE;
                    555:        }
                    556: 
                    557: 
                    558:     case TTEMP:
                    559:       varinfo = lookup(p);
                    560:       if (varinfo->sets == 0)
                    561:        return SCSAFE;
                    562:       else
                    563:        return SCFREE;
                    564: 
                    565:     case TADDR:
                    566:       s1 = anex(p->addrblock.memoffset);
                    567:       s2 = anex(p->addrblock.vleng);
                    568: 
                    569:       varinfo = lookup(p);
                    570: 
                    571:       if (varinfo->sets == 0)
                    572:        switch (s1)
                    573:          {
                    574:          case SCSAFE:
                    575:                if (s2 == SCFREE) removesafe(&p->addrblock.memoffset);
                    576:                return s2;
                    577: 
                    578:          case SCFREE:
                    579:                if (s2 == SCSAFE) removesafe(&p->addrblock.vleng);
                    580:                return SCFREE;
                    581:          }
                    582: 
                    583:       if (s1 == SCSAFE) removesafe(&p->addrblock.memoffset);
                    584:       if (s2 == SCSAFE) removesafe(&p->addrblock.vleng);
                    585:       return SCFREE;
                    586:     
                    587:        
                    588:     default:
                    589:       return SCFREE;
                    590:     }
                    591: }
                    592: 
                    593: 
                    594: LOCAL safefactor(p)
                    595: expptr p;
                    596: 
                    597: {
                    598:   if ( ! ISCONST(p))
                    599:     return NO;
                    600: 
                    601:   if (ISINT(p->constblock.vtype))
                    602:     if (abs(p->constblock.const.ci) <= 1)
                    603:       return YES;
                    604: 
                    605:   if (ISREAL(p->constblock.vtype))
                    606:     if (abs(p->constblock.const.cd[0]) <= 1.0)
                    607:       return YES;
                    608: 
                    609:   return NO;
                    610: }
                    611: 
                    612: 
                    613: LOCAL int worthcost(p)
                    614: expptr p;
                    615: 
                    616: {
                    617:   int cost;
                    618:   chainp q;
                    619:   expptr memoffset,vleng;
                    620: 
                    621:   if (p == ENULL)
                    622:     return NO;
                    623: 
                    624:   switch (p->tag)
                    625:     {
                    626:     case TCONST:
                    627:       return NO;
                    628: 
                    629:     case TTEMP:
                    630:       return NO;
                    631: 
                    632:     case TADDR:
                    633:       if ((memoffset = p->addrblock.memoffset) && ! ISCONST(memoffset))
                    634:        return YES;
                    635:       else if ((vleng = p->addrblock.vleng) && ! ISCONST(vleng))
                    636:        return YES;
                    637:       else
                    638:        return NO;
                    639: 
                    640:     case TEXPR:
                    641:       return YES;
                    642: 
                    643:     case TLIST:
                    644:       cost = 0;
                    645:       for (q = p->listblock.listp; q; q = q->nextp)
                    646:        {
                    647:        if (worthcost ((expptr) q->datap))
                    648:          return YES;
                    649:        cost++;
                    650:        }
                    651:       return (cost>2 ? YES : NO);
                    652: 
                    653:     default:
                    654:       return NO;
                    655:     }
                    656: }
                    657: 
                    658: 
                    659: LOCAL removesafe(refexpr)
                    660: expptr *refexpr;
                    661: 
                    662: {
                    663:   expptr ep;
                    664:   Tempp ap;
                    665:   Slotp newslot;
                    666: 
                    667:   extern Addrp gettemp();
                    668: 
                    669:   ep = *refexpr;
                    670:   if (! worthcost(ep))
                    671:     return;
                    672: 
                    673:   if (ep->tag == TEXPR && ep->exprblock.opcode == OPASSIGN)
                    674:     {
                    675:       if (ep->exprblock.leftp->tag != TTEMP)
                    676:        fatal ("non-TEMP in assignment to be moved in optloop");
                    677: 
                    678:       newslot = optinsert (SKEQ, ep, 0, 0, first);
                    679:       *refexpr = ep->exprblock.leftp;
                    680:     }
                    681:   else
                    682:     {
                    683:       ap = (Tempp) gettemp(ep);
                    684:       newslot = optinsert (SKEQ, mkexpr(OPASSIGN,cpexpr(ap),ep), 0, 0, first);
                    685:       *refexpr = (expptr) ap;
                    686:       optinsert (SKFRTEMP,ap->memalloc,0,0,last->next);
                    687:     }
                    688: 
                    689:   comocount++;
                    690:   if (!newcode)
                    691:     newcode = newslot;
                    692: 
                    693:   return;
                    694: }
                    695: 
                    696: 
                    697: LOCAL Addrp gettemp(p)
                    698: expptr p;
                    699: 
                    700: {
                    701:   return mktemp(p->headblock.vtype, p->headblock.vleng);
                    702: }
                    703: 
                    704: 
                    705: 
                    706: LOCAL movefrtemp (expr)
                    707: Tempp  expr;
                    708: 
                    709: {
                    710:   Slotp        s;
                    711: 
                    712:   if (expr->tag != TTEMP)
                    713:     badtag ("movefrtemp",expr->tag);
                    714: 
                    715:   for (s = first; s; s = s->next)
                    716:     if (s->type == SKFRTEMP && s->expr == (expptr) expr->memalloc)
                    717:       {
                    718:        removeslot (s);
                    719:        insertslot (s,last->next);
                    720:        return;
                    721:       }
                    722: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.