Annotation of researchv10no/cmd/ccom/common/optim.c, revision 1.1.1.1

1.1       root        1: /*     @(#) optim.c: 1.3 1/12/84       */
                      2: 
                      3: # include "mfile1.h"
                      4: 
                      5: # define ISCON(p) (p->in.op==ICON)
                      6: 
                      7: int opdebug = 0;
                      8: NODE *doptim();
                      9: 
                     10: NODE *
                     11: aadjust( p, adj )
                     12: register NODE *p; 
                     13: register adj;
                     14: {
                     15:        /* try to adjust p by adj bits */
                     16:        register NODE *q;
                     17:        adj = BITOOR(adj);
                     18:        switch( p->tn.op )
                     19:        {
                     20:        case ICON:
                     21:                p->tn.lval += adj;
                     22:                return( p );
                     23:        default:
                     24:                /* construct a + node */
                     25: mkplus:
                     26:                return( block( PLUS, p, bcon(adj), p->fn.type,
                     27:                p->fn.cdim, p->fn.csiz ) );
                     28:        case PLUS:
                     29:                q = p->in.right;
                     30:                if( q->tn.op != ICON ) goto mkplus;
                     31:                q->tn.lval += adj;
                     32:                return( p );
                     33:        case MINUS:
                     34:                q = p->in.right;
                     35:                if( q->tn.op != ICON ) goto mkplus;
                     36:                q->tn.lval -= adj;
                     37:                return( p );
                     38:        }
                     39: }
                     40: 
                     41: adjust( p, adj )
                     42: register NODE *p; 
                     43: register adj;
                     44: {
                     45:        /* handle adjustment of scalars by adj bits */
                     46: 
                     47:        switch( p->tn.op )
                     48:        {
                     49:        case NAME:
                     50:        case VAUTO:
                     51:        case VPARAM:
                     52:                p->tn.lval += BITOOR(adj);
                     53:                return( 1 );
                     54:        case STAR:
                     55:                p->in.left = aadjust( p->in.left, adj );
                     56:                return( 1 );
                     57:        default:
                     58:                return( 0 );
                     59:        }
                     60: }
                     61: 
                     62: # ifdef NOSIMPSTR
                     63: # ifndef MYSIMPSTR
                     64: simpstr( d, s ) 
                     65: {
                     66:          return( STRTY ); 
                     67: }
                     68: # endif
                     69: # else
                     70: TWORD
                     71: simpstr( d, s ) 
                     72: {
                     73:        /* return STRTY if not, and CHAR, INT, SHORT, or LONG if simple */
                     74:        register sz, al;
                     75: 
                     76:        sz = tsize( STRTY, d, s );
                     77:        al = talign( STRTY, s );
                     78:        if( sz == SZINT /*&& !( al % ALINT)*/ ) return( INT );
                     79:        else if( sz == SZCHAR /*&& !( al % ALCHAR)*/ ) return( CHAR );
                     80:        else if( sz == SZLONG /*&& !( al % ALLONG)*/ ) return( LONG );
                     81:        else if( sz == SZSHORT /*&& !( al % ALSHORT)*/ ) return( SHORT );
                     82:        return( STRTY );
                     83: }
                     84: # endif
                     85: 
                     86: tydown( p )
                     87: NODE *p; 
                     88: {
                     89:        /* reflect the type of p downwards, as appropriate */
                     90:        /* the type is typically getting smaller */
                     91:        /* returns 1 if it makes a real change */
                     92: 
                     93:        TWORD t;
                     94:        NODE *l, *r;
                     95:        int flag;
                     96: 
                     97: #ifndef NODBG
                     98:        if( opdebug ) 
                     99:        {
                    100:                printf( "tydown(%d) called with:\n", p-node );
                    101:                eprint( p );
                    102:        }
                    103: #endif
                    104:        t = p->tn.type;
                    105:        if( ISPTR(t) || ISARY(t) ) return(0);
                    106: 
                    107:        /* work these types down into the tree */
                    108: 
                    109:        flag = 0;
                    110: 
                    111:        switch( p->tn.op ) 
                    112:        {
                    113: 
                    114:        case AND:
                    115:        case OR:
                    116:        case PLUS:
                    117:        case MINUS:
                    118:        case ER:
                    119:        case COMOP:
                    120: #ifndef NODBG
                    121:                if( opdebug ) 
                    122:                {
                    123:                        printf( "tydown:\n" );
                    124:                        eprint( p );
                    125:                }
                    126: #endif
                    127:                r = p->in.right;
                    128:                if( bigsize(r->tn.type) > bigsize(p->tn.type ) ) 
                    129:                {
                    130:                        r = makety( r, t, 0, (int) t );
                    131:                        tydown( r );
                    132:                        p->in.right = doptim( r );
                    133: #ifndef NODBG
                    134:                        if( opdebug ) 
                    135:                        {
                    136:                                printf( "tydown(%d), after doptim(R):\n",
                    137:                                p-node );
                    138:                                eprint(p);
                    139:                        }
                    140: #endif
                    141:                        flag = 1;
                    142:                }
                    143:                if( p->tn.op == COMOP ) return( flag );
                    144:                /* FALLTHRU */
                    145: 
                    146:        case UNARY MINUS:
                    147:        case COMPL:
                    148:                l = p->in.left;
                    149:                if( bigsize(l->tn.type) > bigsize(p->tn.type ) ) 
                    150:                {
                    151:                        l = makety( l, t, 0, (int) t );
                    152:                        tydown( l );
                    153:                        p->in.left = doptim( l );
                    154: #ifndef NODBG
                    155:                        if( opdebug ) 
                    156:                        {
                    157:                                printf( "tydown(%d), after doptim(L):\n",
                    158:                                p-node );
                    159:                                eprint(p);
                    160:                        }
                    161: #endif
                    162:                        flag = 1;
                    163:                }
                    164:                return(flag);
                    165:        }
                    166:        return( 0 );                    /* no change */
                    167: }
                    168: 
                    169: # ifndef MYCONVERT
                    170: NODE *
                    171: sconvert( p )
                    172: register NODE *p; 
                    173: {
                    174:        register TWORD t, lt;
                    175:        register NODE *l;
                    176:        register o;
                    177: 
                    178:        /* optimize CONV nodes */
                    179:        /* the unsigned-ness is ignored */
                    180:        /* if the CONV involves floats or doubles, retain unless null */
                    181:        /* if the CONV makes things bigger, retain */
                    182:        /* if the CONV keeps things the same size, just paint the type */
                    183:        /* if the CONV makes things smaller, adjust the addressing with
                    184:        ** memory references, and paint the new type 
                    185:        */
                    186:        /* if a pointer is being converted, convert as if it were PTRTYPE */
                    187:        /* finally, if CONV converts a constant, do it in place */
                    188: again:
                    189: #ifndef NODBG
                    190:        if( opdebug ) 
                    191:        {
                    192:                printf( "sconvert(%d) called:\n", p-node );
                    193:                eprint( p );
                    194:        }
                    195: #endif
                    196:        if( p->tn.op != CONV ) cerror( "sconvert" );
                    197:        l = p->in.left;
                    198:        t = p->tn.type;
                    199:        lt = l->tn.type;
                    200:        o = l->tn.op;
                    201: 
                    202:        if( o == FCON )
                    203:        {
                    204:                /* for a floating point const, paint type,
                    205:                ** round when it is output */
                    206:                if( t == FLOAT || t == DOUBLE ) goto paint;
                    207:                /* otherwise, convert it to long and treat as long conversion */
                    208:                l->tn.op = ICON;
                    209:                l->tn.lval = l->fpn.dval;  /* MACHINE-DEPENDENT CONVERSION */
                    210:                l->tn.rval = NONAME;
                    211:                goto icon;
                    212:        }
                    213: 
                    214:        if( o==CONV && cbigger( l ) )
                    215:        {
                    216: merge:
                    217:                p->in.left = l->in.left;
                    218:                l->tn.op = FREE;
                    219:                tydown( p );
                    220:                goto again;
                    221:        }
                    222:        if( t == lt && (t == DOUBLE || t == FLOAT) )
                    223:            goto paint;                 /* float over float, double over double */
                    224:        if(     t==FLOAT || t==DOUBLE || t == VOID
                    225:            || lt==FLOAT || lt==DOUBLE ) return( p );
                    226: 
                    227:        if( ISUNSIGNED(t) ) t = DEUNSIGN(t);
                    228:        if( ISUNSIGNED(lt) ) lt = DEUNSIGN(lt);
                    229:        if( ISPTR(lt) )
                    230: # ifdef MEMONLY
                    231:                if( o==STAR || o==NAME || o==VAUTO || o==VPARAM )
                    232: # endif
                    233:                        lt = PTRTYPE;
                    234:        if( t == lt ) goto paint;
                    235:        if( ISPTR(lt) || ISARY(lt) ) return(p);
                    236: 
                    237:        if( o == ICON )
                    238:        {
                    239: icon:
                    240:                l->tn.lval = ccast( l->tn.lval, p->tn.type );
                    241: paint:
                    242:                l->tn.type = p->tn.type;
                    243:                l->fn.csiz = p->fn.csiz;
                    244:                l->fn.cdim = p->fn.cdim;
                    245:                p->tn.op = FREE;
                    246:                if( tydown(l) ) 
                    247:                {
                    248:                        l = doptim(l);
                    249:                }
                    250:                return( l );
                    251:        }
                    252:        if( cbigger(p) ) return( p );
                    253:        /* p makes things smaller */
                    254:        if( o==CONV )
                    255:        {
                    256:                /* two conversions in a row: the second makes things smaller */
                    257:                /* make them into one */
                    258:                goto merge;
                    259:        }
                    260:        if( o==STAR || o==NAME || o==VAUTO || o==VPARAM ) 
                    261:        {
                    262:                /* memory reference: determine the adjustment */
                    263: # ifdef RTOLBYTES
                    264: # ifdef LOWINT
                    265:                if( lt == LONG ) if( !adjust( l, LOWINT )) cerror( "adj" );
                    266: # endif
                    267: # else 
                    268:                register adj = 0;
                    269:                if( lt == LONG ) adj = SZLONG;
                    270:                else if( lt == INT ) adj = SZINT;
                    271:                else if( lt == SHORT ) adj = SZSHORT;
                    272:                else cerror( "sconv:lt 0%o", lt );
                    273:                if( t == INT ) adj -= SZINT;
                    274:                else if( t == SHORT ) adj -= SZSHORT;
                    275:                else if( t == CHAR ) adj -= SZCHAR;
                    276:                else cerror( "sconv:t 0%o", t );
                    277: # ifdef LOWINT
                    278:                if( lt == LONG ) adj += LOWINT;
                    279: # endif
                    280:                if( adj ) if( !adjust( l, adj ) ) cerror( "adj1" );
                    281: # endif
                    282:        }
                    283: 
                    284:        /* other cases are where it is computed into a reg; */
                    285:        /* simply paint the type */
                    286:        /* must avoid clobbering the type for assignment nodes */
                    287:        /* however, we must copy (e.g., apply the CONV) for register vars */
                    288:        /* also, can't paint type over fields */
                    289:        if( o == REG || asgop(o) || o == FLD ) return( p );
                    290:        goto paint;
                    291: }
                    292: # endif
                    293: 
                    294: NODE *
                    295: pvconvert( p )
                    296: register NODE *p; 
                    297: {
                    298:        /* p is a CONV node; convert */
                    299:        /* this does something only when the descendent is not a ptr */
                    300:        register NODE *l;
                    301:        register int o;
                    302:        l = p->in.left;
                    303:        if( ISPTR( l->tn.type ) ) return( clocal(p) );
                    304: # ifdef MEMONLY
                    305:        o = l->tn.op;
                    306:        if( o==STAR || o==NAME || o==VAUTO || o==VPARAM || o==ICON )
                    307: # endif
                    308:        {
                    309:                 /* optimize this reference */
                    310:                /* sconvert and optimize to PTRTYPE */
                    311:                l = makety( l, PTRTYPE, 0, PTRTYPE );
                    312:                if( l->tn.op == CONV ) l = sconvert( l );
                    313:                l->tn.type = p->tn.type;
                    314:                l->fn.cdim = p->fn.cdim;
                    315:                l->fn.csiz = p->fn.csiz;
                    316:                p->tn.op = FREE;
                    317:                p = l;
                    318:        }
                    319:        return( clocal(p) );
                    320: }
                    321: 
                    322: NODE *
                    323: fortarg( p )
                    324: register NODE *p; 
                    325: {
                    326:        /* fortran function arguments */
                    327: 
                    328:        if( p->in.op == CM )
                    329:        {
                    330:                p->in.left = fortarg( p->in.left );
                    331:                p->in.right = fortarg( p->in.right );
                    332:                return(p);
                    333:        }
                    334:        while( ISPTR(p->in.type) )
                    335:        {
                    336:                p = buildtree( STAR, p, NIL );
                    337:        }
                    338:        return( optim(p) );
                    339: }
                    340: 
                    341: /* mapping relationals when the sides are reversed */
                    342: short revrel[] =
                    343: {
                    344:         EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT 
                    345: };
                    346: 
                    347: #ifndef NODBG
                    348: #define REPORT(x) if(opdebug){printf( "optim did\n"); eprint(x);}
                    349: #else
                    350: # define REPORT(x)
                    351: #endif
                    352: NODE *
                    353: doptim(p)
                    354: register NODE *p; 
                    355: {
                    356:        /* local optimizations, most of which are machine independent */
                    357:        /* doptim is called for each node by optim; it assumes that
                    358:        ** the children of p are already optimized 
                    359:        */
                    360:        /* p is not a leaf */
                    361:        register NODE *l, *r, *sp;
                    362:        register o, i;
                    363:        register TWORD t;
                    364: 
                    365: #ifndef NODBG
                    366:        if( opdebug ) 
                    367:        {
                    368:                printf( "doptim called on:\n" );
                    369:                eprint(p);
                    370:        }
                    371: #endif
                    372: 
                    373:        if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p);
                    374:        switch( optype( o = p->tn.op ) ) 
                    375:        {
                    376:        case BITYPE:
                    377:                r = p->in.right;
                    378:                /* FALLTHRU */
                    379:        case UTYPE:
                    380:                l = p->in.left;
                    381:                break;
                    382:        case LTYPE:
                    383:                /* nothing more to do (after doing the enum stuff) */
                    384:                return( p );
                    385:        }
                    386:        sp = conval( p );
                    387:        /* return only if conval did something */
                    388:        if( sp != p ) return( doptim(sp) );
                    389: #ifndef NODBG
                    390:        if( opdebug ) 
                    391:        {
                    392:                printf( "doptim works on:\n" );
                    393:                eprint(p);
                    394:        }
                    395: #endif
                    396:        switch(o)
                    397:        {
                    398:        case COMOP:     /* maybe simpstr changed the type of the right */
                    399:                if(p->in.type != r->in.type) {
                    400:                        p->in.type = r->in.type;
                    401:                        /* anything else? */
                    402:                        REPORT(p);
                    403:                }
                    404:                return(p);
                    405:        case CONV:
                    406:                /* someday, make pvconvert and sconvert the same */
                    407:                return( ISPTR(p->tn.type)?pvconvert(p):sconvert(p) );
                    408:        case ASG PLUS:
                    409:        case ASG MINUS:
                    410:        case ASG AND:
                    411:        case ASG OR:
                    412:        case ASG ER:
                    413:        case ASG LS:
                    414:        case ASG RS:
                    415:        case ASG MUL:
                    416:        case ASG DIV:
                    417:        case ASG MOD:
                    418:                /* if conversion ops on the lhs, transfer them to the rhs */
                    419:                t = l->in.type;
                    420: 
                    421:                /* (CONV A) op= B  into A op= (CONV B)
                    422:                ** this only holds if the result depends only on the
                    423:                ** low order part of B (e.g., that part of B that
                    424:                ** is the width of A
                    425:                ** this is not true for /=, %=, or floats */
                    426: 
                    427:                if( l->tn.op == CONV && t!=FLOAT && t!=DOUBLE
                    428:                        && o!=ASG DIV && o != ASG MOD )
                    429:                {
                    430:                        p->in.left = l->in.left;
                    431:                        l->tn.op = FREE;
                    432:                        l = l->in.left;
                    433:                        r = makety( r, p->in.type, p->fn.cdim, p->fn.csiz );
                    434:                        p->in.right = doptim( r );
                    435:                }
                    436:                if( !nncon(r) ) break;  /* no more optimization */
                    437:                /* get rid of 0 ops that don't change anything... */
                    438:                if( !r->tn.lval && (o==ASG PLUS || o==ASG MINUS || o==ASG OR ||
                    439:                    o==ASG ER || o==ASG LS || o==ASG RS) )
                    440:                {
                    441:                        /* the answer is the lhs */
                    442:                        goto bless;
                    443:                }
                    444:                if( r->tn.lval == 1 && (o==ASG MUL || o==ASG DIV) ) 
                    445:                {
                    446:                        /* the answer is the lhs */
                    447:                        goto bless;
                    448:                }
                    449:                if( (i = ispow2( r->tn.lval ))>=0 && o==ASG MUL ) 
                    450:                {
                    451:                        o = p->in.op = ASG LS;
                    452:                        r->tn.lval = i;
                    453:                }
                    454:                break;
                    455:        case LS:
                    456:        case RS:
                    457:                if( !nncon(r) || r->tn.lval )
                    458:                        break;  /* do nothing */
                    459:                goto bless;  /* shifts by 0 */
                    460:        case FORTCALL:
                    461:                p->in.right = fortarg( r );
                    462:                break;
                    463:        case UNARY AND:
                    464:                switch( l->tn.op ) 
                    465:                {
                    466:                case STAR:
                    467:                        /* fake up to use setuleft */
                    468:                        l->tn.op = FREE;
                    469:                        l=l->in.left;
                    470:                        goto setuleft;
                    471:                case VAUTO:
                    472:                case VPARAM:
                    473:                case TEMP:
                    474:                        /* the next two lines come from short structs */
                    475:                case CALL:
                    476:                case UNARY CALL:
                    477:                        break;
                    478: 
                    479:                case RNODE:
                    480: # ifdef ARGSRET
                    481:                        /* RNODE disappears if structure simple */
                    482:                        if( simpstr( p->fn.cdim, p->fn.csiz ) == STRTY ) 
                    483:                        {
                    484:                                /* complicated: make it look like first arg */
                    485:                                l->tn.op = VPARAM;
                    486:                                l->tn.lval = BITOOR(ARGINIT);
                    487:                                l->tn.rval = NONAME;
                    488:                        }
                    489:                        break;
                    490: #else
                    491: # ifdef STATSRET
                    492:                        /* simple structures will disappear */
                    493:                        if( simpstr( p->fn.cdim, p->fn.csiz ) != STRTY ) break;
                    494:                        /* otherwise, make & RNODE into ICON for static area */
                    495:                        l->tn.rval = -strftn;
                    496: # else
                    497:                        break; /* & of RNODE is just fine */
                    498: #endif
                    499: #endif
                    500:                case NAME:
                    501: # ifdef ANDABLE
                    502:                        if( !ANDABLE(l) ) return(p);
                    503: # endif
                    504:                        l->tn.op = ICON;
                    505: setuleft:
                    506:                        /* set the type of lhs with the type of the top */
                    507:                        l->in.type = p->in.type;
                    508:                        l->fn.cdim = p->fn.cdim;
                    509:                        l->fn.csiz = p->fn.csiz;
                    510:                        p->in.op = FREE;
                    511:                        REPORT(l);
                    512:                        return( l );
                    513:                default:
                    514:                        cerror( "& error" );
                    515:                }
                    516:                break;
                    517:        case STCALL:
                    518:        case UNARY STCALL:
                    519:                /* use l in case return type overwritten */
                    520:                t = simpstr( l->fn.cdim, l->fn.csiz );
                    521:                if( t != STRTY ) 
                    522:                {
                    523:                        /* take some care to keep the types OK */
                    524:                        /* the type of the return might well have been
                    525:                        ** overwritten by (say) a structure reference 
                    526:                        */
                    527:                        /* MAY NOT BE QUITE RIGHT IF TWO FLAVORS OF PTR */
                    528:                        l = p;
                    529:                        p->tn.type = DECREF( p->tn.type );
                    530:                        p = buildtree( UNARY AND, l, NIL );
                    531:                        if( o == STCALL ) l->tn.op = CALL;
                    532:                        else l->tn.op = UNARY CALL;
                    533:                        l->fn.type = l->fn.csiz = t;
                    534:                        l->fn.cdim = 0;
                    535:                }
                    536:                break;
                    537:        case STAR:
                    538:                if( p->tn.type == STRTY || p->tn.type == UNIONTY ) 
                    539:                {
                    540:                        p->tn.op = FREE;
                    541:                        REPORT(l);
                    542:                        return( l );
                    543:                }
                    544:                if( l->tn.op == UNARY AND && !callop(l->in.left->tn.op) ) 
                    545:                {
                    546:                        /* & of call used in structure optimization */
                    547:                        /* fake up to use setuleft */
                    548:                        l->tn.op = FREE;
                    549:                        l = l->in.left;
                    550:                        goto setuleft;
                    551:                }
                    552:                if( l->tn.op != ICON ) break;
                    553:                l->tn.op = NAME;
                    554:                goto setuleft;
                    555:        case MINUS:
                    556:                if( !nncon(r) ) break;
                    557:                r->tn.lval = - r->tn.lval;
                    558:                o = p->in.op = PLUS;
                    559:        case MUL:
                    560:        case PLUS:
                    561:        case AND:
                    562:        case OR:
                    563:        case ER:
                    564:                /* commutative ops; for now, just collect constants */
                    565:                /* someday, do it right */
                    566:                if( o==r->tn.op || nncon(l) || ( ISCON(l) && !ISCON(r) ) ) 
                    567:                {
                    568:                        /* make ops tower to the left, not the right */
                    569:                        /* also, put constants on the right */
                    570:                        sp = l;
                    571:                        l = p->in.left = r;
                    572:                        r = p->in.right = sp;
                    573:                }
                    574:                /* do (A + C1) + C2, etc. */
                    575:                /* the number of special cases is horrifying */
                    576:                /* many bugs have been found here; this code is very cautious */
                    577:                /* (A + C1) + C2, where C2 can be a ptr, C1 not */
                    578:                if( o==PLUS && l->tn.op==PLUS && ISCON(r) &&
                    579:                    nncon(l->in.right) )
                    580:                {
                    581:                        p->in.left = l->in.left;
                    582:                        l->tn.op = FREE;
                    583:                        l = l->in.right;
                    584:                        r->tn.lval += l->tn.lval;
                    585:                        l->tn.op = FREE;
                    586:                        return( doptim( p ) );
                    587:                }
                    588:                /* (A + C1) + C2, where C1 can be a ptr, C2 not */
                    589:                if( o==PLUS && l->tn.op==PLUS && nncon(r) &&
                    590:                    ISCON(l->in.right) )
                    591:                {
                    592:                        l->in.right->tn.lval += r->tn.lval;
                    593:                        goto bless;  /* return l as the result */
                    594:                }
                    595:                /* (A - C1) + C2, where C2 can be a ptr, C1 not */
                    596:                if( o==PLUS && l->tn.op==MINUS && ISCON(r) &&
                    597:                    nncon(l->in.right) )
                    598:                {
                    599:                        p->in.left = l->in.left;
                    600:                        l->tn.op = FREE;
                    601:                        l = l->in.right;
                    602:                        r->tn.lval -= l->tn.lval;
                    603:                        l->tn.op = FREE;
                    604:                        return( doptim( p ) );
                    605:                }
                    606:                /* (&A)+C */
                    607:                if( o==PLUS && l->tn.op == UNARY AND && ISCON(r) ) 
                    608:                {
                    609:                        switch( l->in.left->tn.op ) 
                    610:                        {
                    611:                        case NAME:
                    612:                        case VPARAM:
                    613:                        case VAUTO:
                    614:                                l->in.left->tn.lval += r->tn.lval;
                    615:                                goto bless;
                    616:                        }
                    617:                }
                    618:                /* change muls to shifts */
                    619:                if( o==MUL && nncon(r) && (i=ispow2(r->tn.lval))>=0)
                    620:                {
                    621:                        if( i == 0 )
                    622:                        {
                    623:                                 /* multiplication by 1 */
                    624: bless:
                    625:                                /* return l, with the type of p */
                    626:                                l = makety( l, p->tn.type, p->fn.cdim,
                    627:                                p->fn.csiz );
                    628:                                r->tn.op = FREE;
                    629:                                p->tn.op = FREE;
                    630:                                /* if a conversion op was added, optimize */
                    631:                                l = doptim( l );
                    632: #ifndef NODBG
                    633:                                if( opdebug ) 
                    634:                                {
                    635:                                        printf( "optim replaces op1 (%d) by:\n",
                    636:                                        p-node );
                    637:                                        eprint(l);
                    638:                                }
                    639: #endif
                    640:                                return( l );
                    641:                        }
                    642:                        o = p->in.op = LS;
                    643:                        r->tn.lval = i;
                    644:                }
                    645:                /* change +'s of negative consts back to - */
                    646:                if( o==PLUS && nncon(r) && r->tn.lval<0 )
                    647:                {
                    648:                        r->tn.lval = -r->tn.lval;
                    649:                        o = p->in.op = MINUS;
                    650:                }
                    651:                if( nncon(r) && !r->tn.lval && (o==PLUS||o==MINUS) )
                    652:                {
                    653:                        /* get rid of add or subtract of 0 */
                    654:                        goto bless;
                    655:                }
                    656: # ifdef PTRLEFT
                    657:                if( o==PLUS && ISPTR(p->tn.type) && ISPTR(r->tn.type)
                    658: # ifdef CONSRIGHT
                    659:                    && r->tn.op != ICON
                    660: # endif
                    661:                    ) 
                    662:                {
                    663:                         sp = l; 
                    664:                        p->in.left = r; 
                    665:                        p->in.right = sp; 
                    666:                }
                    667: # endif
                    668: # ifdef PTRRIGHT
                    669:                if( o==PLUS && ISPTR(p->tn.type) && ISPTR(l->tn.type)
                    670: # ifdef CONSRIGHT
                    671:                    && r->tn.op != ICON
                    672: # endif
                    673:                    ) 
                    674:                {
                    675:                         sp = l; 
                    676:                        p->in.left = r; 
                    677:                        p->in.right = sp; 
                    678:                }
                    679: # endif
                    680:                break;
                    681:        case DIV:
                    682:                if( nncon( r ) && r->tn.lval == 1 ) goto bless;
                    683:                break;
                    684:        case EQ:
                    685:        case NE:
                    686:        case LT:
                    687:        case LE:
                    688:        case GT:
                    689:        case GE:
                    690:        case ULT:
                    691:        case ULE:
                    692:        case UGT:
                    693:        case UGE:
                    694:                if( ISCON(l) && !ISCON(r) )
                    695:                {
                    696:                        /* exchange operands */
                    697:                        p->in.op = revrel[p->in.op - EQ ];
                    698:                        sp = l;
                    699:                        l = p->in.left = r;
                    700:                        r = p->in.right = sp;
                    701:                }
                    702:                break;
                    703:        case STASG:
                    704:                if( (t=simpstr( p->fn.cdim, p->fn.csiz ) ) != STRTY ) 
                    705:                {
                    706:                        /* rewrite = as simpler */
                    707:                        if( ISPTR(r->tn.type) ) 
                    708:                        {
                    709:                                r = buildtree( STAR, r, NIL );
                    710:                                r->fn.type = r->fn.csiz = t;
                    711:                                r->fn.cdim = 0;
                    712:                                p->in.right = r = doptim( r );
                    713:                        }
                    714:                        l = buildtree( STAR, l, NIL );
                    715:                        l->fn.type = l->fn.csiz = t;
                    716:                        l->fn.cdim = 0;
                    717:                        p->in.left = l = doptim( l );
                    718:                        p->fn.type = p->fn.csiz = t;
                    719:                        p->fn.cdim = 0;
                    720:                        p->fn.op = ASSIGN;
                    721:                        return( p );
                    722:                }
                    723:        case STARG:
                    724:                if( (t=simpstr( p->fn.cdim, p->fn.csiz ) ) != STRTY ) 
                    725:                {
                    726:                        /* rewrite as simpler */
                    727:                        if( ISPTR(l->fn.type) ) 
                    728:                        {
                    729:                                l = buildtree( STAR, l, NIL );
                    730:                                l->fn.type = l->fn.csiz = t;
                    731:                                l->fn.cdim = 0;
                    732:                                p->in.left = l = doptim( l );
                    733:                        }
                    734:                        p->fn.type = p->fn.csiz = (t==LONG ? LONG : INT);
                    735:                        p->fn.cdim = 0;
                    736:                        p->fn.op = FUNARG;
                    737:                        return( p );
                    738:                }
                    739: # ifdef ENDSTRUCT
                    740:                p->in.left = aadjust( l, p->stn.stsize );
                    741: # endif
                    742:                break;
                    743:        }
                    744:        return(p);
                    745: }
                    746: 
                    747: NODE *
                    748: optim( p )
                    749: register NODE *p; 
                    750: {
                    751:        switch( optype( p->tn.op ) )
                    752:        {
                    753:        case BITYPE:
                    754:                p->in.right = optim( p->in.right );
                    755:                /* FALLTHRU */
                    756:        case UTYPE:
                    757:                p->in.left = optim( p->in.left );
                    758:        }
                    759:        return( doptim( p ) );
                    760: }
                    761: 
                    762: ispow2( c ) 
                    763: register CONSZ c; 
                    764: {
                    765:        register i;
                    766:        if( c <= 0 || (c&(c-1)) ) return(-1);
                    767:        for( i=0; c>1; ++i) c >>= 1;
                    768:        return(i);
                    769: }
                    770: 
                    771: nncon( p )
                    772: register NODE *p; 
                    773: {
                    774:        /* is p a constant without a name */
                    775:        return( p->tn.op == ICON && p->tn.rval == NONAME && !ISPTR(p->tn.type));
                    776: }
                    777: 
                    778: /* some routines for debugging and tree transformation */
                    779: #ifndef MYOFFCON
                    780: NODE *
                    781: offcon( off, t, d, s )
                    782: OFFSZ off; 
                    783: TWORD t; 
                    784: {
                    785:        /* return a node, for structure references, which is suitable for
                    786:        ** being added to a pointer of type t, in order to be off bits offset
                    787:        ** into a structure 
                    788:        */
                    789:        register NODE *p;
                    790: 
                    791:        /* t, d, and s are the type, dimension offset, and size offset */
                    792:        /* in general they may be necessary for offcon */
                    793:        p = bcon(0);
                    794:        p->tn.lval = BITOOR(off);
                    795:        p->fn.type = p->fn.csiz = PTRTYPE;
                    796:        return(p);
                    797: }
                    798: # endif
                    799: 
                    800: bccode()
                    801: {
                    802:        /* called just before executing code */
                    803:        /* beware: called several times if there is auto. initialization */
                    804: # ifdef MYBCCODE
                    805:        MYBCCODE;
                    806: # endif
                    807:        p2bbeg( autooff, regvar );
                    808: }

unix.superglobalmegacorp.com

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