|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.