Annotation of researchv9/jerq/sgs/optim/w3opt.c, revision 1.1

1.1     ! root        1: /* @(#) w3opt.c: 1.4 3/27/84                           */
        !             2: /* w3opt.c
        !             3: **
        !             4: **     3B20S three-instruction window improver
        !             5: **
        !             6: **
        !             7: **
        !             8: ** This module contains improvements for three instruction windows,
        !             9: ** of which there aren't many.
        !            10: */
        !            11: 
        !            12: /* #include "defs" -- optim.h takes care of this */
        !            13: #include "optim.h"
        !            14: #include "optutil.h"
        !            15: /* w3opt -- 3-instruction peephole window */
        !            16: 
        !            17: boolean                                        /* true if changes made */
        !            18: w3opt(pf,pl)
        !            19: register NODE * pf;                    /* pointer to first inst. in window */
        !            20: register NODE * pl;                    /* pointer to last inst. in window */
        !            21: {
        !            22:     register NODE * pm = pf->forw;     /* point at middle node */
        !            23: 
        !            24:     int cop1 = pf->op;                 /* op code number of first inst. */
        !            25:     int cop2 = pm->op;                 /* op code number of second */
        !            26:     int cop3 = pl->op;                 /* ... of third */
        !            27: 
        !            28:     int src1 ;                         /* size (bytes) of source of move */
        !            29:     int dst1;                          /* size of destination of move */
        !            30: /* *p++ improvement
        !            31: **
        !            32: ** This improvement rearranges things to facilitate a later 2-instruction
        !            33: ** improvement.  We're looking for the kind of code the compiler generates
        !            34: ** (naively) for *p++.  We want to make an indirect reference possible:
        !            35: **
        !            36: **     movw    O1,R            ->      movw O1,R
        !            37: **     addw2   &n,O1           ->      movX 0(R),O2
        !            38: **     movX    0(R),O2         ->      addw2 &n,O1
        !            39: **
        !            40: ** or
        !            41: **     movw    O1,R            ->      movw O1,R
        !            42: **     addw2   &n,O1           ->      movX O2,0(R)
        !            43: **     movX    O2,0(R)         ->      addw2 &n,O1
        !            44: **
        !            45: **     if O1 is not a register used by O2
        !            46: **     if instruction following movX is not conditional branch, since
        !            47: **       we're setting different condition codes than before
        !            48: **     in the first case, O2 cannot be a register used by O1.
        !            49: **
        !            50: ** Note that this transformation is always correct because:
        !            51: **
        !            52: **     1.  O1 could not use R, or the first 2 instructions wouldn't work.
        !            53: **     2.  O2 can use or set R without problems.
        !            54: */
        !            55: 
        !            56:     if (
        !            57:            cop1 == MOVW
        !            58:        &&  cop2 == ADDW2
        !            59:        &&  ismove(pl,&src1,&dst1)
        !            60:        &&  isreg(pf->op2)
        !            61:        &&  *pm->op1 == '&'             /* immediate operand */
        !            62:        &&  strcmp(pf->op1,pm->op2) == 0
        !            63:        &&  isdeadcc( pl )
        !            64:        &&  ! usesvar(pm->op2,pl->op2)  /* O1 can't use O2 */
        !            65:        )
        !            66:     {
        !            67:        char * R = pf->op2;             /* point at register string */
        !            68:        char * O1 = pf->op1;            /* point at first operand */
        !            69:        char * O2;                      /* second operand */
        !            70: 
        !            71:        if (
        !            72:                (   ( O2 = pl->op2, iszoffset(pl->op1,R) ) /* test 0(R) */
        !            73:                ||  ( O2 = pl->op1, iszoffset(pl->op2,R) )
        !            74:                )
        !            75:            &&  ! usesvar(O2,O1)        /* O2 can't use O1 */
        !            76:            &&  ( isiros( O1 ) || isiros( O2 ) )
        !            77:                                        /* safe for mmio */
        !            78:            )
        !            79:        {
        !            80:            wchange();                  /* change the window */
        !            81:            lexchin(pm,pl);             /* preserve line number info */
        !            82:            exchange(pm);               /* exchange the last two nodes */
        !            83:            swplivecc(pm,pl);       /* swap live/dead info on condtion codes */
        !            84:            return(true);
        !            85:        }
        !            86:     }
        !            87: /* Remove redundant compares (see, also w2opt)
        !            88: **
        !            89: ** On the 3B20S, some instructions do not set all of the result
        !            90: ** indicators correctly.  Consequently it is only safe to remove
        !            91: ** a compare against zero if the following conditional jump only
        !            92: ** tests those bits which are set.  The canonical 3 instruction
        !            93: ** sequence is:
        !            94: **
        !            95: **     op O1,O2[,O3]
        !            96: **     cmpX O[2|3],&0
        !            97: **     jcond foo
        !            98: **
        !            99: ** For the instructions we test here, the only valid conditions to
        !           100: ** jump on are equal (zero) and not equal (non-zero).
        !           101: ** Note that signed tests are picked up correctly in w2opt for those
        !           102: ** instructions that generate correct result indicators.
        !           103: */
        !           104: 
        !           105:     if (
        !           106:            (cop2 == CMPW || cop2 == CMPH || cop2 == CMPB)
        !           107:        &&  strcmp(pm->op2,"&0") == 0
        !           108:        &&  strcmp(dst(pf),pm->op1) == 0
        !           109:        &&  (cop3 == JE || cop3 == JZ || cop3 == JNE || cop3 == JNZ)
        !           110:        &&  (MCOMB <= cop1 && cop1 <= UMODW3)
        !           111:        &&  stype(cop1) == stype(cop2)
        !           112:        &&  isiros(pm->op1)             /* safe from mmio */
        !           113:        )
        !           114:     {
        !           115:        wchange();
        !           116:        ldelin2(pm);                    /* preserve line number info */
        !           117:        mvlivecc(pm);       /* preserve live/dead info on condtion codes */
        !           118:        DELNODE(pm);                    /* delete the compare */
        !           119:        return(true);
        !           120:     }
        !           121:     return(false);
        !           122: }

unix.superglobalmegacorp.com

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