Annotation of researchv9/jerq/sgs/comp/optim.c, revision 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 turns %d into %d\n",p-node,x-node);
        !           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 CONV:
        !           399:                /* someday, make pvconvert and sconvert the same */
        !           400:                return( ISPTR(p->tn.type)?pvconvert(p):sconvert(p) );
        !           401:        case ASG PLUS:
        !           402:        case ASG MINUS:
        !           403:        case ASG AND:
        !           404:        case ASG OR:
        !           405:        case ASG ER:
        !           406:        case ASG LS:
        !           407:        case ASG RS:
        !           408:        case ASG MUL:
        !           409:        case ASG DIV:
        !           410:        case ASG MOD:
        !           411:                /* if conversion ops on the lhs, transfer them to the rhs */
        !           412:                t = l->in.type;
        !           413: 
        !           414:                /* (CONV A) op= B  into A op= (CONV B)
        !           415:                ** this only holds if the result depends only on the
        !           416:                ** low order part of B (e.g., that part of B that
        !           417:                ** is the width of A
        !           418:                ** this is not true for /=, %=, or floats */
        !           419: 
        !           420:                if( l->tn.op == CONV && t!=FLOAT && t!=DOUBLE
        !           421:                        && o!=ASG DIV && o != ASG MOD )
        !           422:                {
        !           423:                        p->in.left = l->in.left;
        !           424:                        l->tn.op = FREE;
        !           425:                        l = l->in.left;
        !           426:                        r = makety( r, p->in.type, p->fn.cdim, p->fn.csiz );
        !           427:                        p->in.right = doptim( r );
        !           428:                }
        !           429:                if( !nncon(r) ) break;  /* no more optimization */
        !           430:                /* get rid of 0 ops that don't change anything... */
        !           431:                if( !r->tn.lval && (o==ASG PLUS || o==ASG MINUS || o==ASG OR ||
        !           432:                    o==ASG ER || o==ASG LS || o==ASG RS) )
        !           433:                {
        !           434:                        /* the answer is the lhs */
        !           435:                        goto bless;
        !           436:                }
        !           437:                if( r->tn.lval == 1 && (o==ASG MUL || o==ASG DIV) ) 
        !           438:                {
        !           439:                        /* the answer is the lhs */
        !           440:                        goto bless;
        !           441:                }
        !           442:                if( (i = ispow2( r->tn.lval ))>=0 && o==ASG MUL ) 
        !           443:                {
        !           444:                        o = p->in.op = ASG LS;
        !           445:                        r->tn.lval = i;
        !           446:                }
        !           447:                break;
        !           448:        case LS:
        !           449:        case RS:
        !           450:                if( !nncon(r) || r->tn.lval )
        !           451:                        break;  /* do nothing */
        !           452:                goto bless;  /* shifts by 0 */
        !           453:        case FORTCALL:
        !           454:                p->in.right = fortarg( r );
        !           455:                break;
        !           456:        case UNARY AND:
        !           457:                switch( l->tn.op ) 
        !           458:                {
        !           459:                case STAR:
        !           460:                        /* fake up to use setuleft */
        !           461:                        l->tn.op = FREE;
        !           462:                        l=l->in.left;
        !           463:                        goto setuleft;
        !           464:                case VAUTO:
        !           465:                case VPARAM:
        !           466:                case TEMP:
        !           467:                        /* the next two lines come from short structs */
        !           468:                case CALL:
        !           469:                case UNARY CALL:
        !           470:                        break;
        !           471: 
        !           472:                case RNODE:
        !           473: # ifdef ARGSRET
        !           474:                        /* RNODE disappears if structure simple */
        !           475:                        if( simpstr( p->fn.cdim, p->fn.csiz ) == STRTY ) 
        !           476:                        {
        !           477:                                /* complicated: make it look like first arg */
        !           478:                                l->tn.op = VPARAM;
        !           479:                                l->tn.lval = BITOOR(ARGINIT);
        !           480:                                l->tn.rval = NONAME;
        !           481:                        }
        !           482:                        break;
        !           483: #else
        !           484: # ifdef STATSRET
        !           485:                        /* simple structures will disappear */
        !           486:                        if( simpstr( p->fn.cdim, p->fn.csiz ) != STRTY ) break;
        !           487:                        /* otherwise, make & RNODE into ICON for static area */
        !           488:                        l->tn.rval = -strftn;
        !           489: # else
        !           490:                        break; /* & of RNODE is just fine */
        !           491: #endif
        !           492: #endif
        !           493:                case NAME:
        !           494: # ifdef ANDABLE
        !           495:                        if( !ANDABLE(l) ) return(p);
        !           496: # endif
        !           497:                        l->tn.op = ICON;
        !           498: setuleft:
        !           499:                        /* set the type of lhs with the type of the top */
        !           500:                        l->in.type = p->in.type;
        !           501:                        l->fn.cdim = p->fn.cdim;
        !           502:                        l->fn.csiz = p->fn.csiz;
        !           503:                        p->in.op = FREE;
        !           504:                        REPORT(l);
        !           505:                        return( l );
        !           506:                default:
        !           507:                        cerror( "& error" );
        !           508:                }
        !           509:                break;
        !           510:        case STCALL:
        !           511:        case UNARY STCALL:
        !           512:                /* use l in case return type overwritten */
        !           513:                t = simpstr( l->fn.cdim, l->fn.csiz );
        !           514:                if( t != STRTY ) 
        !           515:                {
        !           516:                        /* take some care to keep the types OK */
        !           517:                        /* the type of the return might well have been
        !           518:                        ** overwritten by (say) a structure reference 
        !           519:                        */
        !           520:                        /* MAY NOT BE QUITE RIGHT IF TWO FLAVORS OF PTR */
        !           521:                        l = p;
        !           522:                        p->tn.type = DECREF( p->tn.type );
        !           523:                        p = buildtree( UNARY AND, l, NIL );
        !           524:                        if( o == STCALL ) l->tn.op = CALL;
        !           525:                        else l->tn.op = UNARY CALL;
        !           526:                        l->fn.type = l->fn.csiz = t;
        !           527:                        l->fn.cdim = 0;
        !           528:                }
        !           529:                break;
        !           530:        case STAR:
        !           531:                if( p->tn.type == STRTY || p->tn.type == UNIONTY ) 
        !           532:                {
        !           533:                        p->tn.op = FREE;
        !           534:                        REPORT(l);
        !           535:                        return( l );
        !           536:                }
        !           537:                if( l->tn.op == UNARY AND && !callop(l->in.left->tn.op) ) 
        !           538:                {
        !           539:                        /* & of call used in structure optimization */
        !           540:                        /* fake up to use setuleft */
        !           541:                        l->tn.op = FREE;
        !           542:                        l = l->in.left;
        !           543:                        goto setuleft;
        !           544:                }
        !           545:                if( l->tn.op != ICON ) break;
        !           546:                l->tn.op = NAME;
        !           547:                goto setuleft;
        !           548:        case MINUS:
        !           549:                if( !nncon(r) ) break;
        !           550:                r->tn.lval = - r->tn.lval;
        !           551:                o = p->in.op = PLUS;
        !           552:        case MUL:
        !           553:        case PLUS:
        !           554:        case AND:
        !           555:        case OR:
        !           556:        case ER:
        !           557:                /* commutative ops; for now, just collect constants */
        !           558:                /* someday, do it right */
        !           559:                if( o==r->tn.op || nncon(l) || ( ISCON(l) && !ISCON(r) ) ) 
        !           560:                {
        !           561:                        /* make ops tower to the left, not the right */
        !           562:                        /* also, put constants on the right */
        !           563:                        sp = l;
        !           564:                        l = p->in.left = r;
        !           565:                        r = p->in.right = sp;
        !           566:                }
        !           567:                /* do (A + C1) + C2, etc. */
        !           568:                /* the number of special cases is horrifying */
        !           569:                /* many bugs have been found here; this code is very cautious */
        !           570:                /* (A + C1) + C2, where C2 can be a ptr, C1 not */
        !           571:                if( o==PLUS && l->tn.op==PLUS && ISCON(r) &&
        !           572:                    nncon(l->in.right) )
        !           573:                {
        !           574:                        p->in.left = l->in.left;
        !           575:                        l->tn.op = FREE;
        !           576:                        l = l->in.right;
        !           577:                        r->tn.lval += l->tn.lval;
        !           578:                        l->tn.op = FREE;
        !           579:                        return( doptim( p ) );
        !           580:                }
        !           581:                /* (A + C1) + C2, where C1 can be a ptr, C2 not */
        !           582:                if( o==PLUS && l->tn.op==PLUS && nncon(r) &&
        !           583:                    ISCON(l->in.right) )
        !           584:                {
        !           585:                        l->in.right->tn.lval += r->tn.lval;
        !           586:                        goto bless;  /* return l as the result */
        !           587:                }
        !           588:                /* (A - C1) + C2, where C2 can be a ptr, C1 not */
        !           589:                if( o==PLUS && l->tn.op==MINUS && ISCON(r) &&
        !           590:                    nncon(l->in.right) )
        !           591:                {
        !           592:                        p->in.left = l->in.left;
        !           593:                        l->tn.op = FREE;
        !           594:                        l = l->in.right;
        !           595:                        r->tn.lval -= l->tn.lval;
        !           596:                        l->tn.op = FREE;
        !           597:                        return( doptim( p ) );
        !           598:                }
        !           599:                /* (&A)+C */
        !           600:                if( o==PLUS && l->tn.op == UNARY AND && ISCON(r) ) 
        !           601:                {
        !           602:                        switch( l->in.left->tn.op ) 
        !           603:                        {
        !           604:                        case NAME:
        !           605:                        case VPARAM:
        !           606:                        case VAUTO:
        !           607:                                l->in.left->tn.lval += r->tn.lval;
        !           608:                                goto bless;
        !           609:                        }
        !           610:                }
        !           611:                /* change muls to shifts */
        !           612:                if( o==MUL && nncon(r) && (i=ispow2(r->tn.lval))>=0)
        !           613:                {
        !           614:                        if( i == 0 )
        !           615:                        {
        !           616:                                 /* multiplication by 1 */
        !           617: bless:
        !           618:                                /* return l, with the type of p */
        !           619:                                l = makety( l, p->tn.type, p->fn.cdim,
        !           620:                                p->fn.csiz );
        !           621:                                r->tn.op = FREE;
        !           622:                                p->tn.op = FREE;
        !           623:                                /* if a conversion op was added, optimize */
        !           624:                                l = doptim( l );
        !           625: #ifndef NODBG
        !           626:                                if( opdebug ) 
        !           627:                                {
        !           628:                                        printf( "optim replaces op1 (%d) by:\n",
        !           629:                                        p-node );
        !           630:                                        eprint(l);
        !           631:                                }
        !           632: #endif
        !           633:                                return( l );
        !           634:                        }
        !           635:                        o = p->in.op = LS;
        !           636:                        r->tn.lval = i;
        !           637:                }
        !           638:                /* change +'s of negative consts back to - */
        !           639:                if( o==PLUS && nncon(r) && r->tn.lval<0 )
        !           640:                {
        !           641:                        r->tn.lval = -r->tn.lval;
        !           642:                        o = p->in.op = MINUS;
        !           643:                }
        !           644:                if( nncon(r) && !r->tn.lval && (o==PLUS||o==MINUS) )
        !           645:                {
        !           646:                        /* get rid of add or subtract of 0 */
        !           647:                        goto bless;
        !           648:                }
        !           649: # ifdef PTRLEFT
        !           650:                if( o==PLUS && ISPTR(p->tn.type) && ISPTR(r->tn.type)
        !           651: # ifdef CONSRIGHT
        !           652:                    && r->tn.op != ICON
        !           653: # endif
        !           654:                    ) 
        !           655:                {
        !           656:                         sp = l; 
        !           657:                        p->in.left = r; 
        !           658:                        p->in.right = sp; 
        !           659:                }
        !           660: # endif
        !           661: # ifdef PTRRIGHT
        !           662:                if( o==PLUS && ISPTR(p->tn.type) && ISPTR(l->tn.type)
        !           663: # ifdef CONSRIGHT
        !           664:                    && r->tn.op != ICON
        !           665: # endif
        !           666:                    ) 
        !           667:                {
        !           668:                         sp = l; 
        !           669:                        p->in.left = r; 
        !           670:                        p->in.right = sp; 
        !           671:                }
        !           672: # endif
        !           673:                break;
        !           674:        case DIV:
        !           675:                if( nncon( r ) && r->tn.lval == 1 ) goto bless;
        !           676:                break;
        !           677:        case EQ:
        !           678:        case NE:
        !           679:        case LT:
        !           680:        case LE:
        !           681:        case GT:
        !           682:        case GE:
        !           683:        case ULT:
        !           684:        case ULE:
        !           685:        case UGT:
        !           686:        case UGE:
        !           687:                if( ISCON(l) && !ISCON(r) )
        !           688:                {
        !           689:                        /* exchange operands */
        !           690:                        p->in.op = revrel[p->in.op - EQ ];
        !           691:                        sp = l;
        !           692:                        l = p->in.left = r;
        !           693:                        r = p->in.right = sp;
        !           694:                }
        !           695:                break;
        !           696:        case STASG:
        !           697:                if( (t=simpstr( p->fn.cdim, p->fn.csiz ) ) != STRTY ) 
        !           698:                {
        !           699:                        /* rewrite = as simpler */
        !           700:                        if( ISPTR(r->tn.type) ) 
        !           701:                        {
        !           702:                                r = buildtree( STAR, r, NIL );
        !           703:                                r->fn.type = r->fn.csiz = t;
        !           704:                                r->fn.cdim = 0;
        !           705:                                p->in.right = r = doptim( r );
        !           706:                        }
        !           707:                        l = buildtree( STAR, l, NIL );
        !           708:                        l->fn.type = l->fn.csiz = t;
        !           709:                        l->fn.cdim = 0;
        !           710:                        p->in.left = l = doptim( l );
        !           711:                        p->fn.type = p->fn.csiz = t;
        !           712:                        p->fn.cdim = 0;
        !           713:                        p->fn.op = ASSIGN;
        !           714:                        return( p );
        !           715:                }
        !           716:        case STARG:
        !           717:                if( (t=simpstr( p->fn.cdim, p->fn.csiz ) ) != STRTY ) 
        !           718:                {
        !           719:                        /* rewrite as simpler */
        !           720:                        if( ISPTR(l->fn.type) ) 
        !           721:                        {
        !           722:                                l = buildtree( STAR, l, NIL );
        !           723:                                l->fn.type = l->fn.csiz = t;
        !           724:                                l->fn.cdim = 0;
        !           725:                                p->in.left = l = doptim( l );
        !           726:                        }
        !           727:                        p->fn.type = p->fn.csiz = (t==LONG ? LONG : INT);
        !           728:                        p->fn.cdim = 0;
        !           729:                        p->fn.op = FUNARG;
        !           730:                        return( p );
        !           731:                }
        !           732: # ifdef ENDSTRUCT
        !           733:                p->in.left = aadjust( l, p->stn.stsize );
        !           734: # endif
        !           735:                break;
        !           736:        }
        !           737:        return(p);
        !           738: }
        !           739: 
        !           740: NODE *
        !           741: optim( p )
        !           742: register NODE *p; 
        !           743: {
        !           744:        switch( optype( p->tn.op ) )
        !           745:        {
        !           746:        case BITYPE:
        !           747:                p->in.right = optim( p->in.right );
        !           748:                /* FALLTHRU */
        !           749:        case UTYPE:
        !           750:                p->in.left = optim( p->in.left );
        !           751:        }
        !           752:        return( doptim( p ) );
        !           753: }
        !           754: 
        !           755: ispow2( c ) 
        !           756: register CONSZ c; 
        !           757: {
        !           758:        register i;
        !           759:        if( c <= 0 || (c&(c-1)) ) return(-1);
        !           760:        for( i=0; c>1; ++i) c >>= 1;
        !           761:        return(i);
        !           762: }
        !           763: 
        !           764: nncon( p )
        !           765: register NODE *p; 
        !           766: {
        !           767:        /* is p a constant without a name */
        !           768:        return( p->tn.op == ICON && p->tn.rval == NONAME && !ISPTR(p->tn.type));
        !           769: }
        !           770: 
        !           771: /* some routines for debugging and tree transformation */
        !           772: #ifndef MYOFFCON
        !           773: NODE *
        !           774: offcon( off, t, d, s )
        !           775: OFFSZ off; 
        !           776: TWORD t; 
        !           777: {
        !           778:        /* return a node, for structure references, which is suitable for
        !           779:        ** being added to a pointer of type t, in order to be off bits offset
        !           780:        ** into a structure 
        !           781:        */
        !           782:        register NODE *p;
        !           783: 
        !           784:        /* t, d, and s are the type, dimension offset, and size offset */
        !           785:        /* in general they may be necessary for offcon */
        !           786:        p = bcon(0);
        !           787:        p->tn.lval = BITOOR(off);
        !           788:        p->fn.type = p->fn.csiz = PTRTYPE;
        !           789:        return(p);
        !           790: }
        !           791: # endif
        !           792: 
        !           793: bccode()
        !           794: {
        !           795:        /* called just before executing code */
        !           796:        /* beware: called several times if there is auto. initialization */
        !           797: /*# ifdef SDB
        !           798: /*     static bcclev;
        !           799: /*     if( blevel != bcclev )
        !           800: /*     {
        !           801: /*             bcclev = blevel;
        !           802: /*             pstab( S_LBRAC, blevel-1 );
        !           803: /*     }
        !           804: /*# endif
        !           805: /**/
        !           806: # ifdef MYBCCODE
        !           807:        MYBCCODE;
        !           808: # endif
        !           809:        p2bbeg( autooff, regvar );
        !           810: }

unix.superglobalmegacorp.com

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