|
|
1.1 ! root 1: #include <u.h> ! 2: #include <libc.h> ! 3: #include <bio.h> ! 4: #include <ctype.h> ! 5: #define Extern extern ! 6: #include "parl.h" ! 7: #include "globl.h" ! 8: ! 9: void ! 10: peep(void) ! 11: { ! 12: Reg *r, *r1, *r2; ! 13: Inst *p; ! 14: int t; ! 15: /* ! 16: * complete R structure ! 17: */ ! 18: t = 0; ! 19: for(r=firstr; r!=R; r=r1) { ! 20: r1 = r->next; ! 21: if(r1 == R) ! 22: break; ! 23: p = r->prog->next; ! 24: while(p != r1->prog) ! 25: switch(p->op) { ! 26: default: ! 27: r2 = rega(); ! 28: r->next = r2; ! 29: r2->next = r1; ! 30: ! 31: r2->prog = p; ! 32: r2->p1 = r; ! 33: r->s1 = r2; ! 34: r2->s1 = r1; ! 35: r1->p1 = r2; ! 36: ! 37: r = r2; ! 38: t++; ! 39: ! 40: case ADATA: ! 41: case ADYNT: ! 42: case AINIT: ! 43: case AGLOBL: ! 44: case ANAME: ! 45: p = p->next; ! 46: } ! 47: } ! 48: ! 49: loop1: ! 50: t = 0; ! 51: for(r=firstr; r!=R; r=r->next) { ! 52: p = r->prog; ! 53: if(p->op == AMOVW || p->op == AFMOVF || p->op == AFMOVD) ! 54: if(regtyp(&p->dst)) { ! 55: if(regtyp(&p->src1)) ! 56: if(p->src1.type == p->dst.type) { ! 57: if(copyprop(r)) { ! 58: excise(r); ! 59: t++; ! 60: } else ! 61: if(subprop(r) && copyprop(r)) { ! 62: excise(r); ! 63: t++; ! 64: } ! 65: } ! 66: if(regzer(&p->src1)) ! 67: if(p->dst.type == A_REG) { ! 68: p->src1.type = A_REG; ! 69: p->src1.reg = 0; ! 70: if(copyprop(r)) { ! 71: excise(r); ! 72: t++; ! 73: } else ! 74: if(subprop(r) && copyprop(r)) { ! 75: excise(r); ! 76: t++; ! 77: } ! 78: } ! 79: } ! 80: } ! 81: if(t) ! 82: goto loop1; ! 83: } ! 84: ! 85: void ! 86: excise(Reg *r) ! 87: { ! 88: Inst *p; ! 89: ! 90: p = r->prog; ! 91: p->op = ANOP; ! 92: p->src1 = zprog.src1; ! 93: p->dst = zprog.dst; ! 94: p->reg = zprog.reg; /**/ ! 95: } ! 96: ! 97: Reg* ! 98: uniqp(Reg *r) ! 99: { ! 100: Reg *r1; ! 101: ! 102: r1 = r->p1; ! 103: if(r1 == R) { ! 104: r1 = r->p2; ! 105: if(r1 == R || r1->p2next != R) ! 106: return R; ! 107: } else ! 108: if(r->p2 != R) ! 109: return R; ! 110: return r1; ! 111: } ! 112: ! 113: Reg* ! 114: uniqs(Reg *r) ! 115: { ! 116: Reg *r1; ! 117: ! 118: r1 = r->s1; ! 119: if(r1 == R) { ! 120: r1 = r->s2; ! 121: if(r1 == R) ! 122: return R; ! 123: } else ! 124: if(r->s2 != R) ! 125: return R; ! 126: return r1; ! 127: } ! 128: ! 129: regzer(Adres *a) ! 130: { ! 131: ! 132: if(a->type == A_CONST) ! 133: if(a->sym == ZeroS) ! 134: if(a->ival == 0) ! 135: return 1; ! 136: if(a->type == A_REG) ! 137: if(a->reg == 0) ! 138: return 1; ! 139: return 0; ! 140: } ! 141: ! 142: regtyp(Adres *a) ! 143: { ! 144: ! 145: if(a->type == A_REG) { ! 146: if(a->reg != 0) ! 147: return 1; ! 148: return 0; ! 149: } ! 150: if(a->type == A_FREG) ! 151: return 1; ! 152: return 0; ! 153: } ! 154: ! 155: /* ! 156: * the idea is to substitute ! 157: * one register for another ! 158: * from one MOV to another ! 159: * MOV a, R0 ! 160: * ADD b, R0 / no use of R1 ! 161: * MOV R0, R1 ! 162: * would be converted to ! 163: * MOV a, R1 ! 164: * ADD b, R1 ! 165: * MOV R1, R0 ! 166: * hopefully, then the former or latter MOV ! 167: * will be eliminated by copy propagation. ! 168: */ ! 169: int ! 170: subprop(Reg *r0) ! 171: { ! 172: Inst *p; ! 173: Adres *v1, *v2; ! 174: Reg *r; ! 175: int t; ! 176: ! 177: p = r0->prog; ! 178: v1 = &p->src1; ! 179: if(!regtyp(v1)) ! 180: return 0; ! 181: v2 = &p->dst; ! 182: if(!regtyp(v2)) ! 183: return 0; ! 184: for(r=uniqp(r0); r!=R; r=uniqp(r)) { ! 185: if(uniqs(r) == R) ! 186: break; ! 187: p = r->prog; ! 188: switch(p->op) { ! 189: case AJMPL: ! 190: return 0; ! 191: ! 192: case AADD: ! 193: case ASUB: ! 194: case ASLL: ! 195: case ASRL: ! 196: case ASRA: ! 197: case AOR: ! 198: case AAND: ! 199: case AXOR: ! 200: case AMUL: ! 201: case ADIV: ! 202: case ADIVL: ! 203: case AMOD: ! 204: case AMODL: ! 205: ! 206: case AFADDD: ! 207: case AFADDF: ! 208: case AFSUBD: ! 209: case AFSUBF: ! 210: case AFMULD: ! 211: case AFMULF: ! 212: case AFDIVD: ! 213: case AFDIVF: ! 214: if(p->dst.type == v1->type) ! 215: if(p->dst.reg == v1->reg) { ! 216: if(p->reg == Nreg) ! 217: p->reg = p->dst.reg; ! 218: goto gotit; ! 219: } ! 220: break; ! 221: ! 222: case AFMOVF: ! 223: case AFMOVD: ! 224: case AMOVW: ! 225: if(p->dst.type == v1->type) ! 226: if(p->dst.reg == v1->reg) ! 227: goto gotit; ! 228: break; ! 229: } ! 230: if(copyau(&p->src1, v2) || ! 231: copyau1(p, v2) || ! 232: copyau(&p->dst, v2)) ! 233: break; ! 234: if(copysub(&p->src1, v1, v2, 0) || ! 235: copysub1(p, v1, v2, 0) || ! 236: copysub(&p->dst, v1, v2, 0)) ! 237: break; ! 238: } ! 239: return 0; ! 240: ! 241: gotit: ! 242: copysub(&p->dst, v1, v2, 1); ! 243: if(opt('P')) { ! 244: print("gotit: %a->%a\n%i", v1, v2, r->prog); ! 245: if(p->src1.type == v2->type) ! 246: print(" excise"); ! 247: print("\n"); ! 248: } ! 249: for(r=uniqs(r); r!=r0; r=uniqs(r)) { ! 250: p = r->prog; ! 251: copysub(&p->src1, v1, v2, 1); ! 252: copysub1(p, v1, v2, 1); ! 253: copysub(&p->dst, v1, v2, 1); ! 254: if(opt('P')) ! 255: print("%i\n", r->prog); ! 256: } ! 257: t = v1->reg; ! 258: v1->reg = v2->reg; ! 259: v2->reg = t; ! 260: if(opt('P')) ! 261: print("%i last\n", r->prog); ! 262: return 1; ! 263: } ! 264: ! 265: /* ! 266: * The idea is to remove redundant copies. ! 267: * v1->v2 F=0 ! 268: * (use v2 s/v2/v1/)* ! 269: * set v1 F=1 ! 270: * use v2 return fail ! 271: * ----------------- ! 272: * v1->v2 F=0 ! 273: * (use v2 s/v2/v1/)* ! 274: * set v1 F=1 ! 275: * set v2 return success ! 276: */ ! 277: int ! 278: copyprop(Reg *r0) ! 279: { ! 280: Inst *p; ! 281: Adres *v1, *v2; ! 282: Reg *r; ! 283: ! 284: p = r0->prog; ! 285: v1 = &p->src1; ! 286: v2 = &p->dst; ! 287: if(copyas(v1, v2)) ! 288: return 1; ! 289: for(r=firstr; r!=R; r=r->next) ! 290: r->active = 0; ! 291: return copy1(v1, v2, r0->s1, 0); ! 292: } ! 293: ! 294: copy1(Adres *v1, Adres *v2, Reg *r, int f) ! 295: { ! 296: int t; ! 297: Inst *p; ! 298: ! 299: if(r->active) { ! 300: if(opt('P')) ! 301: print("act set; return 1\n"); ! 302: return 1; ! 303: } ! 304: r->active = 1; ! 305: if(opt('P')) ! 306: print("copy %a->%a f=%d\n", v1, v2, f); ! 307: for(; r != R; r = r->s1) { ! 308: p = r->prog; ! 309: if(opt('P')) ! 310: print("%i", p); ! 311: if(!f && uniqp(r) == R) { ! 312: f = 1; ! 313: if(opt('P')) ! 314: print("; merge; f=%d", f); ! 315: } ! 316: t = copyu(p, v2, A); ! 317: switch(t) { ! 318: case 2: /* rar, cant split */ ! 319: if(opt('P')) ! 320: print("; %arar; return 0\n", v2); ! 321: return 0; ! 322: ! 323: case 3: /* set */ ! 324: if(opt('P')) ! 325: print("; %aset; return 1\n", v2); ! 326: return 1; ! 327: ! 328: case 1: /* used, substitute */ ! 329: case 4: /* use and set */ ! 330: if(f) { ! 331: if(!opt('P')) ! 332: return 0; ! 333: if(t == 4) ! 334: print("; %aused+set and f=%d; return 0\n", v2, f); ! 335: else ! 336: print("; %aused and f=%d; return 0\n", v2, f); ! 337: return 0; ! 338: } ! 339: if(copyu(p, v2, v1)) { ! 340: if(opt('P')) ! 341: print("; sub fail; return 0\n"); ! 342: return 0; ! 343: } ! 344: if(opt('P')) ! 345: print("; sub%a/%a", v2, v1); ! 346: if(t == 4) { ! 347: if(opt('P')) ! 348: print("; %aused+set; return 1\n", v2); ! 349: return 1; ! 350: } ! 351: break; ! 352: } ! 353: if(!f) { ! 354: t = copyu(p, v1, A); ! 355: if(!f && (t == 2 || t == 3 || t == 4)) { ! 356: f = 1; ! 357: if(opt('P')) ! 358: print("; %aset and !f; f=%d", v1, f); ! 359: } ! 360: } ! 361: if(opt('P')) ! 362: print("\n"); ! 363: if(r->s2) ! 364: if(!copy1(v1, v2, r->s2, f)) ! 365: return 0; ! 366: } ! 367: return 1; ! 368: } ! 369: ! 370: /* ! 371: * return ! 372: * 1 if v only used (and substitute), ! 373: * 2 if read-alter-rewrite ! 374: * 3 if set ! 375: * 4 if set and used ! 376: * 0 otherwise (not touched) ! 377: */ ! 378: int ! 379: copyu(Inst *p, Adres *v, Adres *s) ! 380: { ! 381: ! 382: switch(p->op) { ! 383: ! 384: default: ! 385: if(opt('P')) ! 386: print(" (???)"); ! 387: return 2; ! 388: ! 389: ! 390: case ANOP: /* read, write */ ! 391: case AMOVW: ! 392: case AMOVH: ! 393: case AMOVHU: ! 394: case AMOVB: ! 395: case AMOVBU: ! 396: ! 397: case AFMOVF: ! 398: case AFMOVD: ! 399: case AFMOVDW: ! 400: case AFMOVWD: ! 401: case AFMOVFW: ! 402: case AFMOVWF: ! 403: case AFMOVFD: ! 404: case AFMOVDF: ! 405: if(s != A) { ! 406: if(copysub(&p->src1, v, s, 1)) ! 407: return 1; ! 408: if(!copyas(&p->dst, v)) ! 409: if(copysub(&p->dst, v, s, 1)) ! 410: return 1; ! 411: return 0; ! 412: } ! 413: if(copyas(&p->dst, v)) { ! 414: if(copyau(&p->src1, v)) ! 415: return 4; ! 416: return 3; ! 417: } ! 418: if(copyau(&p->src1, v)) ! 419: return 1; ! 420: if(copyau(&p->dst, v)) ! 421: return 1; ! 422: return 0; ! 423: ! 424: case AADD: /* read read write */ ! 425: case ASUB: ! 426: case ASLL: ! 427: case ASRL: ! 428: case ASRA: ! 429: case AOR: ! 430: case AAND: ! 431: case AXOR: ! 432: case AMUL: ! 433: case ADIV: ! 434: case ADIVL: ! 435: case AMOD: ! 436: case AMODL: ! 437: ! 438: case AFADDF: ! 439: case AFADDD: ! 440: case AFSUBF: ! 441: case AFSUBD: ! 442: case AFMULF: ! 443: case AFMULD: ! 444: case AFDIVF: ! 445: case AFDIVD: ! 446: if(s != A) { ! 447: if(copysub(&p->src1, v, s, 1)) ! 448: return 1; ! 449: if(copysub1(p, v, s, 1)) ! 450: return 1; ! 451: if(!copyas(&p->dst, v)) ! 452: if(copysub(&p->dst, v, s, 1)) ! 453: return 1; ! 454: return 0; ! 455: } ! 456: if(copyas(&p->dst, v)) { ! 457: if(p->reg == Nreg) ! 458: p->reg = p->dst.reg; ! 459: if(copyau(&p->src1, v)) ! 460: return 4; ! 461: if(copyau1(p, v)) ! 462: return 4; ! 463: return 3; ! 464: } ! 465: if(copyau(&p->src1, v)) ! 466: return 1; ! 467: if(copyau1(p, v)) ! 468: return 1; ! 469: if(copyau(&p->dst, v)) ! 470: return 1; ! 471: return 0; ! 472: ! 473: case ABA: /* no reference */ ! 474: case ABCC: ! 475: case ABCS: ! 476: case ABE: ! 477: case ABG: ! 478: case ABGE: ! 479: case ABGU: ! 480: case ABL: ! 481: case ABLE: ! 482: case ABLEU: ! 483: case ABN: ! 484: case ABNE: ! 485: case ABNEG: ! 486: case ABPOS: ! 487: case ABVC: ! 488: case ABVS: ! 489: case AFBA: ! 490: case AFBE: ! 491: case AFBG: ! 492: case AFBGE: ! 493: case AFBL: ! 494: case AFBLE: ! 495: case AFBLG: ! 496: case AFBN: ! 497: case AFBNE: ! 498: case AFBO: ! 499: case AFBU: ! 500: case AFBUE: ! 501: case AFBUG: ! 502: case AFBUGE: ! 503: case AFBUL: ! 504: case AFBULE: ! 505: break; ! 506: ! 507: case ACMP: /* read read */ ! 508: case AFCMPD: ! 509: case AFCMPF: ! 510: if(s != A) { ! 511: if(copysub(&p->src1, v, s, 1)) ! 512: return 1; ! 513: return copysub(&p->dst, v, s, 1); ! 514: } ! 515: if(copyau(&p->src1, v)) ! 516: return 1; ! 517: if(copyau(&p->dst, v)) ! 518: return 1; ! 519: break; ! 520: ! 521: case AJMP: /* funny */ ! 522: if(s != A) { ! 523: if(copysub(&p->dst, v, s, 1)) ! 524: return 1; ! 525: return 0; ! 526: } ! 527: if(copyau(&p->dst, v)) ! 528: return 1; ! 529: return 0; ! 530: ! 531: case ARETURN: /* funny */ ! 532: if(v->type == A_REG && v->reg == REGRET) ! 533: return 2; ! 534: if(v->type == A_FREG && v->reg == FREGRET) ! 535: return 2; ! 536: ! 537: case AJMPL: /* funny */ ! 538: if(v->type == A_REG) { ! 539: if(v->reg == Regspass) ! 540: return 2; ! 541: if(v->reg == RegSP) ! 542: return 2; ! 543: } ! 544: if(s != A) { ! 545: if(copysub(&p->dst, v, s, 1)) ! 546: return 1; ! 547: return 0; ! 548: } ! 549: if(copyau(&p->dst, v)) ! 550: return 4; ! 551: return 3; ! 552: ! 553: case ATEXT: /* funny */ ! 554: if(v->type == A_REG) ! 555: if(v->reg == Regspass) ! 556: return 3; ! 557: return 0; ! 558: } ! 559: return 0; ! 560: } ! 561: ! 562: int ! 563: a2type(Inst *p) ! 564: { ! 565: ! 566: switch(p->op) { ! 567: case AADD: ! 568: case ASUB: ! 569: case ASLL: ! 570: case ASRL: ! 571: case ASRA: ! 572: case AOR: ! 573: case AAND: ! 574: case AXOR: ! 575: case AMUL: ! 576: case ADIV: ! 577: case ADIVL: ! 578: case AMOD: ! 579: case AMODL: ! 580: return A_REG; ! 581: ! 582: case AFADDF: ! 583: case AFADDD: ! 584: case AFSUBF: ! 585: case AFSUBD: ! 586: case AFMULF: ! 587: case AFMULD: ! 588: case AFDIVF: ! 589: case AFDIVD: ! 590: return A_FREG; ! 591: } ! 592: return A_NONE; ! 593: } ! 594: ! 595: /* ! 596: * direct reference, ! 597: * could be set/use depending on ! 598: * semantics ! 599: */ ! 600: int ! 601: copyas(Adres *a, Adres *v) ! 602: { ! 603: ! 604: if(regtyp(v)) ! 605: if(a->type == v->type) ! 606: if(a->reg == v->reg) ! 607: return 1; ! 608: return 0; ! 609: } ! 610: ! 611: /* ! 612: * either direct or indirect ! 613: */ ! 614: int ! 615: copyau(Adres *a, Adres *v) ! 616: { ! 617: ! 618: if(copyas(a, v)) ! 619: return 1; ! 620: if(v->type == A_REG) ! 621: if(a->type == A_INDREG) ! 622: if(v->reg == a->reg) ! 623: return 1; ! 624: return 0; ! 625: } ! 626: ! 627: int ! 628: copyau1(Inst *p, Adres *v) ! 629: { ! 630: ! 631: if(regtyp(v)) ! 632: if(p->src1.type == v->type || p->dst.type == v->type) ! 633: if(p->reg == v->reg) { ! 634: if(a2type(p) != v->type) ! 635: print("botch a2type %i\n", p); ! 636: return 1; ! 637: } ! 638: return 0; ! 639: } ! 640: ! 641: /* ! 642: * substitute s for v in a ! 643: * return failure to substitute ! 644: */ ! 645: int ! 646: copysub(Adres *a, Adres *v, Adres *s, int f) ! 647: { ! 648: ! 649: if(f) ! 650: if(copyau(a, v)) ! 651: a->reg = s->reg; ! 652: return 0; ! 653: } ! 654: ! 655: int ! 656: copysub1(Inst *p1, Adres *v, Adres *s, int f) ! 657: { ! 658: ! 659: if(f) ! 660: if(copyau1(p1, v)) ! 661: p1->reg = s->reg; ! 662: return 0; ! 663: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.