Annotation of researchv9/jerq/sgs/optim/w3opt.c, revision 1.1.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.