Annotation of researchv10no/cmd/ccom/common/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 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.