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

1.1       root        1: /* %W% (Berkeley) %G% */
                      2: #include "defs.h"
                      3: #include "optim.h"
                      4: 
                      5: 
                      6: 
                      7: /*
                      8:  *             Information buffered for each slot type
                      9:  *
                     10:  *  slot type         expptr          integer          pointer
                     11:  *
                     12:  *  IFN                        expr            label           -
                     13:  *  GOTO               -               label           -
                     14:  *  LABEL              -               label           -
                     15:  *  EQ                 expr            -               -
                     16:  *  CALL               expr            -               -
                     17:  *  CMGOTO             expr            num             labellist*
                     18:  *  STOP               expr            -               -
                     19:  *  DOHEAD             [1]             -               ctlframe*
                     20:  *  ENDDO              [1]             -               ctlframe*
                     21:  *  ARIF               expr            -               labellist*
                     22:  *  RETURN             expr            label           -
                     23:  *  ASGOTO             expr            -               labellist*
                     24:  *  PAUSE              expr            -               -
                     25:  *  ASSIGN             expr            label           -
                     26:  *  SKIOIFN            expr            label           -
                     27:  *  SKFRTEMP           expr            -               -
                     28:  *
                     29:  *     Note [1]:  the nullslot field is a pointer to a fake slot which is
                     30:  *     at the end of the slots which may be replaced by this slot.  In
                     31:  *     other words, it looks like this:
                     32:  *             DOHEAD slot
                     33:  *             slot   \
                     34:  *             slot    > ordinary IF, GOTO, LABEL slots which implement the DO
                     35:  *             slot   /
                     36:  *             NULL slot
                     37:  */
                     38: 
                     39: 
                     40: expptr expand();
                     41: 
                     42: Slotp  firstslot = NULL;
                     43: Slotp  lastslot = NULL;
                     44: int    numslots = 0;
                     45: 
                     46: 
                     47: /*
                     48:  *  turns off optimization option
                     49:  */
                     50: 
                     51: optoff()
                     52: 
                     53: {
                     54: flushopt();
                     55: optimflag = 0;
                     56: }
                     57: 
                     58: 
                     59: 
                     60: /*
                     61:  *  initializes the code buffer for optimization
                     62:  */
                     63: 
                     64: setopt()
                     65: 
                     66: {
                     67: register Slotp sp;
                     68: 
                     69: for (sp = firstslot; sp; sp = sp->next)
                     70:        free ( (charptr) sp);
                     71: firstslot = lastslot = NULL;
                     72: numslots = 0;
                     73: }
                     74: 
                     75: 
                     76: 
                     77: /*
                     78:  *  flushes the code buffer
                     79:  */
                     80: 
                     81: LOCAL int alreadycalled = 0;
                     82: 
                     83: flushopt()
                     84: {
                     85: register Slotp sp;
                     86: int savelineno;
                     87: 
                     88: if (alreadycalled) return;     /* to prevent recursive call during errors */
                     89: alreadycalled = 1;
                     90: 
                     91: if (debugflag[1])
                     92:        showbuffer ();
                     93: 
                     94: frtempbuff ();
                     95: 
                     96: savelineno = lineno;
                     97: for (sp = firstslot; sp; sp = sp->next)
                     98:        {
                     99:        putopt(sp);
                    100:         if(sp->ctlinfo) free ( (charptr) sp->ctlinfo);
                    101:         free ( (charptr) sp);
                    102:         numslots--;
                    103:        }
                    104: firstslot = lastslot = NULL;
                    105: numslots = 0;
                    106: clearbb();
                    107: lineno = savelineno;
                    108: 
                    109: alreadycalled = 0;
                    110: }
                    111: 
                    112: 
                    113: 
                    114: /*
                    115:  *  puts out code for the given slot (from the code buffer)
                    116:  */
                    117: 
                    118: LOCAL putopt (sp)
                    119: register Slotp sp;
                    120: {
                    121:        p2flush();
                    122:        lineno = sp->lineno;
                    123:        switch (sp->type) {
                    124:            case SKNULL:
                    125:                break;
                    126:            case SKIFN:
                    127:            case SKIOIFN:
                    128:                putif(sp->expr, sp->label);
                    129:                break;
                    130:            case SKGOTO:
                    131:                putgoto(sp->label);
                    132:                break;
                    133:            case SKCMGOTO:
                    134:                putcmgo(sp->expr, sp->label, sp->ctlinfo);
                    135:                break;
                    136:            case SKCALL:
                    137:                putexpr(sp->expr);
                    138:                break;
                    139:            case SKSTOP:
                    140:                putexpr (call1 (TYSUBR, "s_stop", sp->expr));
                    141:                break;
                    142:            case SKPAUSE:
                    143:                putexpr (call1 (TYSUBR, "s_paus", sp->expr));
                    144:                break;
                    145:            case SKASSIGN:
                    146:                puteq (sp->expr, mkaddcon(sp->label));
                    147:                break;
                    148:            case SKDOHEAD:
                    149:            case SKENDDO:
                    150:                break;
                    151:            case SKEQ:
                    152:                putexpr(sp->expr);
                    153:                break;
                    154:            case SKARIF:
                    155: #define LM   ((struct Labelblock * *)sp->ctlinfo)[0]->labelno 
                    156: #define LZ   ((struct Labelblock * *)sp->ctlinfo)[1]->labelno 
                    157: #define LP   ((struct Labelblock * *)sp->ctlinfo)[2]->labelno 
                    158:                        prarif(sp->expr, LM, LZ, LP);
                    159:                break;
                    160:            case SKASGOTO:
                    161:                putbranch((Addrp) sp->expr);
                    162:                break;
                    163:            case SKLABEL:
                    164:                putlabel(sp->label);
                    165:                break;
                    166:            case SKRETURN:
                    167:                if (sp->expr)
                    168:                        {
                    169:                        putforce(TYINT, sp->expr);
                    170:                        putgoto(sp->label);
                    171:                        }
                    172:                else
                    173:                        putgoto(sp->label);
                    174:                break;
                    175:            case SKFRTEMP:
                    176:                templist = mkchain (sp->expr,templist);
                    177:                break;
                    178:            default:
                    179:                badthing("SKtype", "putopt", sp->type);
                    180:                break;
                    181:        }
                    182: }
                    183: 
                    184: 
                    185: 
                    186: /*
                    187:  *  copies one element of the control stack
                    188:  */
                    189: 
                    190: LOCAL struct Ctlframe *cpframe(p)
                    191: register char *p;
                    192: {
                    193: static int size =  sizeof (struct Ctlframe);
                    194: register int n;
                    195: register char *q;
                    196: struct Ctlframe *q0;
                    197: 
                    198: q0 = ALLOC(Ctlframe);
                    199: q = (char *) q0;
                    200: n = size;
                    201: while(n-- > 0)
                    202:        *q++ = *p++;
                    203: return( q0);
                    204: }
                    205: 
                    206: 
                    207: 
                    208: /*
                    209:  *  copies an array of labelblock pointers
                    210:  */
                    211: 
                    212: LOCAL struct Labelblock **cplabarr(n,arr)
                    213: struct Labelblock *arr[];
                    214: int n;
                    215: {
                    216: struct Labelblock **newarr;
                    217: register char *in, *out;
                    218: register int i,j;
                    219: 
                    220: newarr = (struct Labelblock **) ckalloc (n * sizeof (char *));
                    221: for (i = 0; i < n; i++)
                    222:        {
                    223:        newarr[i] = ALLOC (Labelblock);
                    224:        out = (char *) newarr[i];
                    225:        in = (char *) arr[i];
                    226:        j = sizeof (struct Labelblock);
                    227:        while (j-- > 0)
                    228:                *out++ = *in++;
                    229:        }
                    230: return (newarr);
                    231: }
                    232: 
                    233: 
                    234: 
                    235: /*
                    236:  *  creates a new slot in the code buffer
                    237:  */
                    238: 
                    239: LOCAL Slotp newslot()
                    240: {
                    241: register Slotp sp;
                    242: 
                    243: ++numslots;
                    244: sp = ALLOC( slt );
                    245: sp->next = NULL ;
                    246: if (lastslot)
                    247:        {
                    248:        sp->prev = lastslot;
                    249:        lastslot = lastslot->next = sp;
                    250:        }
                    251: else
                    252:        {
                    253:        firstslot = lastslot = sp;
                    254:        sp->prev = NULL;
                    255:        }
                    256: sp->lineno = lineno;
                    257: return (sp);
                    258: }
                    259: 
                    260: 
                    261: 
                    262: /*
                    263:  *  removes (but not deletes) the specified slot from the code buffer
                    264:  */
                    265: 
                    266: removeslot (sl)
                    267: Slotp  sl;
                    268: 
                    269: {
                    270: if (sl->next)
                    271:        sl->next->prev = sl->prev;
                    272: else
                    273:        lastslot = sl->prev;
                    274: if (sl->prev)
                    275:        sl->prev->next = sl->next;
                    276: else
                    277:        firstslot = sl->next;
                    278: sl->next = sl->prev = NULL;
                    279: 
                    280: --numslots;
                    281: }
                    282: 
                    283: 
                    284: 
                    285: /*
                    286:  *  inserts slot s1 before existing slot s2 in the code buffer;
                    287:  *  appends to end of list if s2 is NULL.
                    288:  */
                    289: 
                    290: insertslot (s1,s2)
                    291: Slotp  s1,s2;
                    292: 
                    293: {
                    294: if (s2)
                    295:        {
                    296:        if (s2->prev)
                    297:                s2->prev->next = s1;
                    298:        else
                    299:                firstslot = s1;
                    300:        s1->prev = s2->prev;
                    301:        s2->prev = s1;
                    302:        }
                    303: else
                    304:        {
                    305:        s1->prev = lastslot;
                    306:        lastslot->next = s1;
                    307:        lastslot = s1;
                    308:        }
                    309: s1->next = s2;
                    310: 
                    311: ++numslots;
                    312: }
                    313: 
                    314: 
                    315: 
                    316: /*
                    317:  *  deletes the specified slot from the code buffer
                    318:  */
                    319: 
                    320: delslot (sl)
                    321: Slotp  sl;
                    322: 
                    323: {
                    324: removeslot (sl);
                    325: 
                    326: if (sl->ctlinfo)
                    327:        free ((charptr) sl->ctlinfo);
                    328: frexpr (sl->expr);
                    329: free ((charptr) sl);
                    330: numslots--;
                    331: }
                    332: 
                    333: 
                    334: 
                    335: /*
                    336:  *  inserts a slot before the specified slot; if given NULL, it is
                    337:  *  inserted at the end of the buffer
                    338:  */
                    339: 
                    340: Slotp optinsert (type,p,l,c,currslot)
                    341: int    type;
                    342: expptr p;
                    343: int    l;
                    344: int    *c;
                    345: Slotp  currslot;
                    346: 
                    347: {
                    348: Slotp  savelast,new;
                    349: 
                    350: savelast = lastslot;
                    351: if (currslot)
                    352:        lastslot = currslot->prev;
                    353: new = optbuff (type,p,l,c);
                    354: new->next = currslot;
                    355: if (currslot)
                    356:        currslot->prev = new;
                    357: new->lineno = -1;      /* who knows what the line number should be ??!! */
                    358: lastslot = savelast;
                    359: return (new);
                    360: }
                    361: 
                    362: 
                    363: 
                    364: /*
                    365:  *  buffers the FRTEMP slots which have been waiting
                    366:  */
                    367: 
                    368: frtempbuff ()
                    369: 
                    370: {
                    371: chainp ht;
                    372: register Slotp sp;
                    373: 
                    374: for (ht = holdtemps; ht; ht = ht->nextp)
                    375:        {
                    376:        sp = newslot();
                    377:                /* this slot actually belongs to some previous source line */
                    378:        sp->lineno = sp->lineno - 1;
                    379:        sp->type = SKFRTEMP;
                    380:        sp->expr = (expptr) ht->datap;
                    381:        sp->label = 0;
                    382:        sp->ctlinfo = NULL;
                    383:        }
                    384: holdtemps = NULL;
                    385: }
                    386: 
                    387: 
                    388: 
                    389: /*
                    390:  *  puts the given information into a slot at the end of the code buffer
                    391:  */
                    392: 
                    393: Slotp optbuff (type,p,l,c)
                    394: int    type;
                    395: expptr p;
                    396: int    l;
                    397: int    *c;
                    398: 
                    399: {
                    400: register Slotp sp;
                    401: 
                    402: if (debugflag[1])
                    403:        {
                    404:        fprintf (diagfile,"-----optbuff-----"); showslottype (type);
                    405:        showexpr (p,0); fprintf (diagfile,"\n");
                    406:        }
                    407: 
                    408: p = expand (p);
                    409: sp = newslot();
                    410: sp->type = type;
                    411: sp->expr = p;
                    412: sp->label = l;
                    413: sp->ctlinfo = NULL;
                    414: switch (type)
                    415:        {
                    416:        case SKCMGOTO:
                    417:                sp->ctlinfo = (int*) cplabarr (l, (struct Labelblock**) c);
                    418:                break;
                    419:        case SKARIF:
                    420:                sp->ctlinfo = (int*) cplabarr (3, (struct Labelblock**) c);
                    421:                break;
                    422:        case SKDOHEAD:
                    423:        case SKENDDO:
                    424:                sp->ctlinfo = (int*) cpframe ((struct Ctlframe*) c);
                    425:                break;
                    426:        default:
                    427:                break;
                    428:        }
                    429: 
                    430: frtempbuff ();
                    431: 
                    432: return (sp);
                    433: }
                    434: 
                    435: 
                    436: 
                    437: /*
                    438:  *  expands the given expression, if possible (e.g., concat, min, max, etc.);
                    439:  *  also frees temporaries when they are indicated as being the last use
                    440:  */
                    441: 
                    442: #define APPEND(z)      \
                    443:        res = res->exprblock.rightp = mkexpr (OPCOMMA, z, newtemp)
                    444: 
                    445: LOCAL expptr expand (p)
                    446: tagptr p;
                    447: 
                    448: {
                    449: Addrp t;
                    450: expptr q;
                    451: Addrp buffmnmx(), buffpower();
                    452: 
                    453: if (!p)
                    454:        return (ENULL);
                    455: switch (p->tag)
                    456:        {
                    457:        case TEXPR:
                    458:                p->exprblock.leftp = expand (p->exprblock.leftp);
                    459:                if (p->exprblock.rightp)
                    460:                        p->exprblock.rightp = expand (p->exprblock.rightp);
                    461:                switch (p->exprblock.opcode)
                    462:                        {
                    463:                        expptr temp;
                    464:                        case OPCONCAT:
                    465:                                t = mktemp (TYCHAR, ICON(lencat(p)));
                    466:                                q = (expptr) cpexpr (p->exprblock.vleng);
                    467:                                buffcat (cpexpr(t),p);
                    468:                                frexpr (t->vleng);
                    469:                                t->vleng = q;
                    470:                                p = (tagptr) t;
                    471:                                break;
                    472:                        case OPMIN:
                    473:                        case OPMAX:
                    474:                                p = (tagptr) buffmnmx (p);
                    475:                                break;
                    476:                        case OPPOWER:
                    477:                                p = (tagptr) buffpower (p);
                    478:                                break;
                    479:                        default:
                    480:                                break;
                    481:                        }
                    482:                break;
                    483: 
                    484:        case TLIST:
                    485:                {
                    486:                chainp t;
                    487:                for (t = p->listblock.listp; t; t = t->nextp)
                    488:                        t->datap = (tagptr) expand (t->datap);
                    489:                }
                    490:                break;
                    491: 
                    492:        case TTEMP:
                    493:                if (p->tempblock.istemp)
                    494:                        frtemp(p);
                    495:                break;
                    496: 
                    497:        default:
                    498:                break;
                    499:        }
                    500: return ((expptr) p);
                    501: }
                    502: 
                    503: 
                    504: 
                    505: /*
                    506:  *  local version of routine putcat in putpcc.c, called by expand
                    507:  */
                    508: 
                    509: LOCAL buffcat(lhs, rhs)
                    510: register Addrp lhs;
                    511: register expptr rhs;
                    512: {
                    513: int n;
                    514: Addrp lp, cp;
                    515: 
                    516: n = ncat(rhs);
                    517: lp = (Addrp) mkaltmpn(n, TYLENG, PNULL);
                    518: cp = (Addrp) mkaltmpn(n, TYADDR, PNULL);
                    519: 
                    520: n = 0;
                    521: buffct1(rhs, lp, cp, &n);
                    522: 
                    523: optbuff (SKCALL, call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n))),
                    524:        0, 0);
                    525: }
                    526: 
                    527: 
                    528: 
                    529: /*
                    530:  *  local version of routine putct1 in putpcc.c, called by expand
                    531:  */
                    532: 
                    533: LOCAL buffct1(q, lp, cp, ip)
                    534: register expptr q;
                    535: register Addrp lp, cp;
                    536: int *ip;
                    537: {
                    538: int i;
                    539: Addrp lp1, cp1;
                    540: 
                    541: if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
                    542:        {
                    543:        buffct1(q->exprblock.leftp, lp, cp, ip);
                    544:        buffct1(q->exprblock.rightp, lp, cp, ip);
                    545:        frexpr(q->exprblock.vleng);
                    546:        free( (charptr) q );
                    547:        }
                    548: else
                    549:        {
                    550:        i = (*ip)++;
                    551:        lp1 = (Addrp) cpexpr(lp);
                    552:        lp1->memoffset = mkexpr(OPPLUS,lp1->memoffset, ICON(i*SZLENG));
                    553:        cp1 = (Addrp) cpexpr(cp);
                    554:        cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR));
                    555:        optbuff (SKEQ, (mkexpr(OPASSIGN, lp1, cpexpr(q->headblock.vleng))),
                    556:                0,0);
                    557:        optbuff (SKEQ, (mkexpr(OPASSIGN, cp1, addrof(expand (q)))), 0, 0);
                    558:        }
                    559: }
                    560: 
                    561: 
                    562: 
                    563: /*
                    564:  *  local version of routine putmnmx in putpcc.c, called by expand
                    565:  */
                    566: 
                    567: LOCAL Addrp buffmnmx(p)
                    568: register expptr p;
                    569: {
                    570: int op, type;
                    571: expptr qp;
                    572: chainp p0, p1;
                    573: Addrp sp, tp;
                    574: Addrp newtemp;
                    575: expptr result, res;
                    576: 
                    577: if(p->tag != TEXPR)
                    578:        badtag("buffmnmx", p->tag);
                    579: 
                    580: type = p->exprblock.vtype;
                    581: op = (p->exprblock.opcode==OPMIN ? OPLT : OPGT );
                    582: p0 = p->exprblock.leftp->listblock.listp;
                    583: free( (charptr) (p->exprblock.leftp) );
                    584: free( (charptr) p );
                    585: 
                    586: sp = mktemp(type, PNULL);
                    587: tp = mktemp(type, PNULL);
                    588: qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp));
                    589: qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp);
                    590: qp = fixexpr(qp);
                    591: 
                    592: newtemp = mktemp (type,PNULL);
                    593: 
                    594: result = res = mkexpr (OPCOMMA,
                    595:        mkexpr( OPASSIGN, cpexpr(sp), p0->datap ), cpexpr(newtemp));
                    596: 
                    597: for(p1 = p0->nextp ; p1 ; p1 = p1->nextp)
                    598:        {
                    599:        APPEND (mkexpr( OPASSIGN, cpexpr(tp), p1->datap ));
                    600:        if(p1->nextp)
                    601:                APPEND (mkexpr (OPASSIGN, cpexpr(sp), cpexpr(qp)) );
                    602:        else
                    603:                APPEND (mkexpr (OPASSIGN, cpexpr(newtemp), qp));
                    604:        }
                    605: 
                    606: frtemp(sp);
                    607: frtemp(tp);
                    608: frtemp(newtemp);
                    609: frchain( &p0 );
                    610: 
                    611: return ( (Addrp) result);
                    612: }
                    613: 
                    614: 
                    615: 
                    616: /*
                    617:  *  Local version of putpower routine from putpcc.c, used by expand().
                    618:  */
                    619: 
                    620: LOCAL Addrp buffpower (p)
                    621: expptr p;
                    622: {
                    623: expptr base;
                    624: Addrp t1, t2;
                    625: ftnint k;
                    626: int type;
                    627: Addrp newtemp;
                    628: expptr res,result;
                    629: 
                    630: if(!ISICON(p->exprblock.rightp) ||
                    631:     (k = p->exprblock.rightp->constblock.const.ci)<2)
                    632:        fatal("buffpower: bad call");
                    633: base = p->exprblock.leftp;
                    634: 
                    635: if (k == 2)
                    636: {
                    637:        expptr prod;
                    638:        prod = mkexpr (OPSTAR,cpexpr(base),cpexpr(base));
                    639:        return ( (Addrp) prod);
                    640: }
                    641: 
                    642: type = base->headblock.vtype;
                    643: newtemp = mktemp (type, PNULL);
                    644: 
                    645: t1 = mktemp(type, PNULL);
                    646: t2 = NULL;
                    647: result = res =
                    648:        mkexpr (OPCOMMA, mkexpr (OPASSIGN,cpexpr(t1),cpexpr(base)),
                    649:        cpexpr (newtemp));
                    650: 
                    651: for( ; (k&1)==0 && k>2 ; k>>=1 )
                    652:        APPEND (mkexpr (OPSTAREQ,cpexpr(t1),cpexpr(t1)));
                    653: 
                    654: if(k == 2)
                    655:        {
                    656:        expptr prod;
                    657:        prod = mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1));
                    658:        APPEND (mkexpr (OPASSIGN,cpexpr(newtemp),cpexpr(prod)));
                    659:        }
                    660: else
                    661:        {
                    662:        t2 = mktemp(type, PNULL);
                    663:        APPEND (mkexpr (OPASSIGN,cpexpr(t2),cpexpr(t1)));
                    664: 
                    665:        for(k>>=1 ; k>1 ; k>>=1)
                    666:                {
                    667:                APPEND (mkexpr (OPSTAREQ,cpexpr(t1),cpexpr(t1)));
                    668:                if(k & 1)
                    669:                        APPEND (mkexpr (OPSTAREQ,cpexpr(t2),cpexpr(t1)));
                    670:                }
                    671:        APPEND (mkexpr (OPASSIGN, cpexpr(newtemp), mkexpr(OPSTAR, cpexpr(t2),
                    672:                        mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) )));
                    673:        }
                    674: frexpr(t1);
                    675: if(t2)
                    676:        frexpr(t2);
                    677: frexpr(p);
                    678: 
                    679: return ( (Addrp) result);
                    680: }

unix.superglobalmegacorp.com

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