|
|
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: #define COL1 32 ! 10: ! 11: Node dummy; ! 12: ! 13: int ! 14: sval(long v) ! 15: { ! 16: ! 17: if(v >= -(1<<12) && v < (1<<12)) ! 18: return 1; ! 19: return 0; ! 20: } ! 21: ! 22: Reg* ! 23: rega(void) ! 24: { ! 25: Reg *r; ! 26: ! 27: r = freer; ! 28: if(r == R) ! 29: r = malloc(sizeof(Reg)); ! 30: else ! 31: freer = r->next; ! 32: ! 33: *r = zreg; ! 34: return r; ! 35: } ! 36: ! 37: int ! 38: rcmp(void *a1, void *a2) ! 39: { ! 40: Rgn *p1, *p2; ! 41: int c1, c2; ! 42: ! 43: p1 = a1; ! 44: p2 = a2; ! 45: c1 = p2->cost; ! 46: c2 = p1->cost; ! 47: if(c1 -= c2) ! 48: return c1; ! 49: return p2->varno - p1->varno; ! 50: } ! 51: ! 52: void ! 53: regopt(Inst *p) ! 54: { ! 55: Reg *r, *r1, *r2; ! 56: int i, z; ! 57: long initpc, val; ! 58: ulong vreg; ! 59: Bits bit; ! 60: Inst *p1; ! 61: struct ! 62: { ! 63: long m; ! 64: long c; ! 65: Reg* p; ! 66: } log5[6], *lp; ! 67: ! 68: initpc = 0; ! 69: firstr = R; ! 70: lastr = R; ! 71: nvar = 0; ! 72: regbits = 0; ! 73: for(z=0; z<BITS; z++) { ! 74: externs.b[z] = 0; ! 75: param.b[z] = 0; ! 76: consts.b[z] = 0; ! 77: addrs.b[z] = 0; ! 78: } ! 79: ! 80: /* ! 81: * pass 1 ! 82: * build aux data structure ! 83: * allocate pcs ! 84: * find use and set of variables ! 85: */ ! 86: val = 5L * 5L * 5L * 5L * 5L; ! 87: lp = log5; ! 88: for(i=0; i<5; i++) { ! 89: lp->m = val; ! 90: lp->c = 0; ! 91: lp->p = R; ! 92: val /= 5L; ! 93: lp++; ! 94: } ! 95: ! 96: for(; p != P; p = p->next) { ! 97: switch(p->op) { ! 98: case ADATA: ! 99: case ADYNT: ! 100: case AINIT: ! 101: case AGLOBL: ! 102: case ANAME: ! 103: continue; ! 104: } ! 105: r = rega(); ! 106: if(firstr == R) { ! 107: initpc = p->pc; ! 108: firstr = r; ! 109: lastr = r; ! 110: } else { ! 111: lastr->next = r; ! 112: r->p1 = lastr; ! 113: lastr->s1 = r; ! 114: lastr = r; ! 115: } ! 116: r->prog = p; ! 117: r->pc = p->pc; ! 118: ! 119: lp = log5; ! 120: for(i=0; i<5; i++) { ! 121: lp->c--; ! 122: if(lp->c <= 0) { ! 123: lp->c = lp->m; ! 124: if(lp->p != R) ! 125: lp->p->log5 = r; ! 126: lp->p = r; ! 127: (lp+1)->c = 0; ! 128: break; ! 129: } ! 130: lp++; ! 131: } ! 132: ! 133: r1 = r->p1; ! 134: if(r1 != R) ! 135: switch(r1->prog->op) { ! 136: case ARETURN: ! 137: case AJMP: ! 138: case ARETT: ! 139: r->p1 = R; ! 140: r1->s1 = R; ! 141: } ! 142: ! 143: /* ! 144: * left side always read ! 145: */ ! 146: bit = mkvar(&p->src1, p->op==AMOVW); ! 147: for(z=0; z<BITS; z++) ! 148: r->use1.b[z] |= bit.b[z]; ! 149: ! 150: /* ! 151: * right side depends on opcode ! 152: */ ! 153: bit = mkvar(&p->dst, 0); ! 154: if(bany(&bit)) ! 155: switch(p->op) { ! 156: default: ! 157: diag(ZeroN, "reg: unknown op: %d", p->op); ! 158: break; ! 159: ! 160: /* ! 161: * right side write ! 162: */ ! 163: case ANOP: ! 164: case AMOVB: ! 165: case AMOVBU: ! 166: case AMOVH: ! 167: case AMOVHU: ! 168: case AMOVW: ! 169: case AFMOVF: ! 170: for(z=0; z<BITS; z++) ! 171: r->set.b[z] |= bit.b[z]; ! 172: break; ! 173: ! 174: /* ! 175: * funny ! 176: */ ! 177: case AFMOVD: ! 178: case ARETURN: ! 179: case AJMPL: ! 180: for(z=0; z<BITS; z++) ! 181: addrs.b[z] |= bit.b[z]; ! 182: break; ! 183: } ! 184: } ! 185: if(firstr == R) ! 186: return; ! 187: ! 188: /* ! 189: * pass 2 ! 190: * turn branch references to pointers ! 191: * build back pointers ! 192: */ ! 193: for(r = firstr; r != R; r = r->next) { ! 194: p = r->prog; ! 195: if(p->dst.type == A_BRANCH) { ! 196: val = p->dst.ival; ! 197: r1 = firstr; ! 198: while(r1 != R) { ! 199: r2 = r1->log5; ! 200: if(r2 != R && val >= r2->pc) { ! 201: r1 = r2; ! 202: continue; ! 203: } ! 204: if(r1->pc == val) ! 205: break; ! 206: r1 = r1->next; ! 207: } ! 208: if(r1 == R) { ! 209: dummy.srcline = p->lineno; ! 210: diag(&dummy, "ref not found\n%i", p); ! 211: continue; ! 212: } ! 213: if(r1 == r) { ! 214: dummy.srcline = p->lineno; ! 215: diag(&dummy, "ref to self\n%i", p); ! 216: continue; ! 217: } ! 218: r->s2 = r1; ! 219: r->p2next = r1->p2; ! 220: r1->p2 = r; ! 221: } ! 222: } ! 223: if(opt('R')) { ! 224: p = firstr->prog; ! 225: print("\n%L %a\n", p->lineno, &p->src1); ! 226: } ! 227: ! 228: /* ! 229: * pass 2.5 ! 230: * find looping structure ! 231: */ ! 232: for(r = firstr; r != R; r = r->next) ! 233: r->active = 0; ! 234: change = 0; ! 235: loopit(firstr); ! 236: if(opt('R') && opt('v')) { ! 237: print("\nlooping structure:\n"); ! 238: for(r = firstr; r != R; r = r->next) { ! 239: print("%d:%i", r->loop, r->prog); ! 240: for(z=0; z<BITS; z++) ! 241: bit.b[z] = r->use1.b[z] | ! 242: r->use2.b[z] | r->set.b[z]; ! 243: if(bany(&bit)) { ! 244: print("%|", COL1); ! 245: if(bany(&r->use1)) ! 246: print(" u1=%B", r->use1); ! 247: if(bany(&r->use2)) ! 248: print(" u2=%B", r->use2); ! 249: if(bany(&r->set)) ! 250: print(" st=%B", r->set); ! 251: } ! 252: print("\n"); ! 253: } ! 254: } ! 255: ! 256: /* ! 257: * pass 3 ! 258: * iterate propagating usage ! 259: * back until flow graph is complete ! 260: */ ! 261: loop1: ! 262: change = 0; ! 263: for(r = firstr; r != R; r = r->next) ! 264: r->active = 0; ! 265: for(r = firstr; r != R; r = r->next) ! 266: if(r->prog->op == ARETURN) ! 267: prop(r, zbits, zbits); ! 268: loop11: ! 269: /* pick up unreachable code */ ! 270: i = 0; ! 271: for(r = firstr; r != R; r = r1) { ! 272: r1 = r->next; ! 273: if(r1 && r1->active && !r->active) { ! 274: prop(r, zbits, zbits); ! 275: i = 1; ! 276: } ! 277: } ! 278: if(i) ! 279: goto loop11; ! 280: if(change) ! 281: goto loop1; ! 282: ! 283: ! 284: /* ! 285: * pass 4 ! 286: * iterate propagating register/variable synchrony ! 287: * forward until graph is complete ! 288: */ ! 289: loop2: ! 290: change = 0; ! 291: for(r = firstr; r != R; r = r->next) ! 292: r->active = 0; ! 293: synch(firstr, zbits); ! 294: if(change) ! 295: goto loop2; ! 296: ! 297: ! 298: /* ! 299: * pass 5 ! 300: * isolate regions ! 301: * calculate costs (paint1) ! 302: */ ! 303: r = firstr; ! 304: if(r) { ! 305: for(z=0; z<BITS; z++) ! 306: bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & ! 307: ~(externs.b[z] | param.b[z] | addrs.b[z] | consts.b[z]); ! 308: if(bany(&bit)) { ! 309: dummy.srcline = r->prog->lineno; ! 310: warn(&dummy, "used and not set: %B", bit); ! 311: if(opt('R') && !opt('w')) ! 312: print("used and not set: %B\n", bit); ! 313: } ! 314: } ! 315: if(opt('R') && opt('v')) ! 316: print("\nprop structure:\n"); ! 317: for(r = firstr; r != R; r = r->next) ! 318: r->act = zbits; ! 319: rgp = region; ! 320: nregion = 0; ! 321: for(r = firstr; r != R; r = r->next) { ! 322: if(opt('R') && opt('v')) ! 323: print("%i\n set = %B; rah = %B; cal = %B\n", ! 324: r->prog, r->set, r->refahead, r->calahead); ! 325: for(z=0; z<BITS; z++) ! 326: bit.b[z] = r->set.b[z] & ! 327: ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]); ! 328: if(bany(&bit)) { ! 329: dummy.srcline = r->prog->lineno; ! 330: warn(&dummy, "set and not used: %B", bit); ! 331: if(opt('R')) ! 332: print("set and not used: %B\n", bit); ! 333: excise(r); ! 334: } ! 335: for(z=0; z<BITS; z++) ! 336: bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]); ! 337: while(bany(&bit)) { ! 338: i = bnum(bit); ! 339: rgp->enter = r; ! 340: rgp->varno = i; ! 341: change = 0; ! 342: if(opt('R') && opt('v')) ! 343: print("\n"); ! 344: paint1(r, i); ! 345: bit.b[i/32] &= ~(1L<<(i%32)); ! 346: if(change <= 0) { ! 347: if(opt('R')) ! 348: print("%L$%d: %B\n", ! 349: r->prog->lineno, change, blsh(i)); ! 350: continue; ! 351: } ! 352: rgp->cost = change; ! 353: nregion++; ! 354: if(nregion >= NRGN) { ! 355: warn(ZeroN, "too many regions"); ! 356: goto brk; ! 357: } ! 358: rgp++; ! 359: } ! 360: } ! 361: brk: ! 362: qsort(region, nregion, sizeof(region[0]), rcmp); ! 363: ! 364: /* ! 365: * pass 6 ! 366: * determine used registers (paint2) ! 367: * replace code (paint3) ! 368: */ ! 369: rgp = region; ! 370: for(i=0; i<nregion; i++) { ! 371: bit = blsh(rgp->varno); ! 372: vreg = paint2(rgp->enter, rgp->varno); ! 373: vreg = allreg(vreg, rgp); ! 374: if(opt('R')) { ! 375: if(rgp->regno >= Nreg) ! 376: print("%L$%d F%d: %B\n", ! 377: rgp->enter->prog->lineno, ! 378: rgp->cost, ! 379: rgp->regno-Nreg, ! 380: bit); ! 381: else ! 382: print("%L$%d R%d: %B\n", ! 383: rgp->enter->prog->lineno, ! 384: rgp->cost, ! 385: rgp->regno, ! 386: bit); ! 387: } ! 388: if(rgp->regno != 0) ! 389: paint3(rgp->enter, rgp->varno, vreg, rgp->regno); ! 390: rgp++; ! 391: } ! 392: /* ! 393: * pass 7 ! 394: * peep-hole on basic block ! 395: */ ! 396: if(!opt('R') || opt('P')) ! 397: peep(); ! 398: ! 399: /* ! 400: * pass 8 ! 401: * recalculate pc ! 402: */ ! 403: val = initpc; ! 404: for(r = firstr; r != R; r = r1) { ! 405: r->pc = val; ! 406: p = r->prog; ! 407: r1 = r->next; ! 408: p1 = P; ! 409: if(r1 != R) ! 410: p1 = r1->prog; ! 411: ! 412: while(p != p1) { ! 413: switch(p->op) { ! 414: default: ! 415: p->pc = val++; ! 416: ! 417: case ADATA: ! 418: case ADYNT: ! 419: case AINIT: ! 420: case AGLOBL: ! 421: case ANAME: ! 422: case ANOP: ! 423: p = p->next; ! 424: } ! 425: } ! 426: } ! 427: pc = val; ! 428: ! 429: /* ! 430: * last pass ! 431: * fix up branches ! 432: * free aux structures ! 433: */ ! 434: if(opt('R')) ! 435: if(bany(&addrs)) ! 436: print("addrs: %B\n", addrs); ! 437: ! 438: r1 = 0; /* set */ ! 439: for(r = firstr; r != R; r = r->next) { ! 440: p = r->prog; ! 441: if(p->dst.type == A_BRANCH) ! 442: p->dst.ival = r->s2->pc; ! 443: r1 = r; ! 444: } ! 445: for(p = firstr->prog; p && p->next; p = p->next) ! 446: while(p->next && p->next->op == ANOP) ! 447: p->next = p->next->next; ! 448: ! 449: if(r1 != R) { ! 450: r1->next = freer; ! 451: freer = firstr; ! 452: } ! 453: } ! 454: ! 455: /* ! 456: * add mov b,rn ! 457: * just after r ! 458: */ ! 459: void ! 460: addmove(Reg *r, int bn, int rn, int f) ! 461: { ! 462: Inst *p, *p1; ! 463: Adres *a; ! 464: Var *v; ! 465: ! 466: if(r->prog->op == AJMPL && r->next) { ! 467: p1 = r->next->prog; ! 468: if(p1->dst.type == A_REG && p1->dst.reg == RegSP) ! 469: r = r->next; ! 470: } ! 471: ! 472: p1 = ai(); ! 473: *p1 = zprog; ! 474: p = r->prog; ! 475: ! 476: p1->next = p->next; ! 477: p->next = p1; ! 478: p1->lineno = p->lineno; ! 479: ! 480: v = var + bn; ! 481: ! 482: a = &p1->dst; ! 483: a->sym = v->sym; ! 484: a->class = v->class; ! 485: a->ival = v->ival; ! 486: a->etype = v->etype; ! 487: a->type = A_INDREG; ! 488: if(a->etype == TARRAY || a->sym == ZeroS) ! 489: a->type = A_CONST; ! 490: ! 491: p1->op = AMOVW; ! 492: if(v->etype == TCHAR) ! 493: p1->op = AMOVBU; ! 494: if(v->etype == TSINT || v->etype == TSUINT) ! 495: p1->op = AMOVH; ! 496: if(v->etype == TFLOAT) ! 497: p1->op = AFMOVD; ! 498: ! 499: p1->src1.type = A_REG; ! 500: p1->src1.reg = rn; ! 501: if(rn >= Nreg) { ! 502: p1->src1.type = A_FREG; ! 503: p1->src1.reg = rn-Nreg; ! 504: } ! 505: if(!f) { ! 506: p1->src1 = *a; ! 507: *a = zprog.src1; ! 508: a->type = A_REG; ! 509: a->reg = rn; ! 510: if(rn >= Nreg) { ! 511: a->type = A_FREG; ! 512: a->reg = rn-Nreg; ! 513: } ! 514: if(v->etype == TCHAR) ! 515: p1->op = AMOVBU; ! 516: if(v->etype == TSUINT) ! 517: p1->op = AMOVHU; ! 518: } ! 519: if(opt('R')) ! 520: print("%i%|.a%i\n", p, COL1, p1); ! 521: } ! 522: ! 523: Bits ! 524: mkvar(Adres *a, int docon) ! 525: { ! 526: Var *v; ! 527: int i, t, n, et, z; ! 528: long o; ! 529: Bits bit; ! 530: Sym *s; ! 531: ! 532: t = a->type; ! 533: if(t == A_REG && a->reg != Nreg) ! 534: regbits |= RtoB(a->reg); ! 535: if(t == A_FREG && a->reg != Nreg) ! 536: regbits |= FtoB(a->reg); ! 537: s = a->sym; ! 538: o = a->ival; ! 539: et = a->etype; ! 540: if(s == ZeroS) { ! 541: if(t != A_CONST || !docon || a->reg != Nreg) ! 542: goto none; ! 543: et = TINT; ! 544: } ! 545: if(t == A_CONST) { ! 546: if(s == ZeroS && sval(o)) ! 547: goto none; ! 548: } ! 549: ! 550: if(s && s->name[0] == '.' && et == TFLOAT) ! 551: goto none; ! 552: ! 553: n = a->class; ! 554: v = var; ! 555: for(i=0; i<nvar; i++) { ! 556: if(s == v->sym) ! 557: if(n == v->class) ! 558: if(o == v->ival) ! 559: goto out; ! 560: v++; ! 561: } ! 562: if(nvar >= NVAR) { ! 563: if(s) ! 564: warn(ZeroN, "variable not optimized: %s", s->name); ! 565: goto none; ! 566: } ! 567: i = nvar; ! 568: nvar++; ! 569: v = &var[i]; ! 570: v->sym = s; ! 571: v->ival = o; ! 572: v->etype = et; ! 573: v->class = n; ! 574: if(opt('R')) ! 575: print("bit=%2d et=%2d %a\n", i, et, a); ! 576: out: ! 577: bit = blsh(i); ! 578: if(n == External || n == Internal || n == Global) ! 579: for(z=0; z<BITS; z++) ! 580: externs.b[z] |= bit.b[z]; ! 581: if(n == Parameter) ! 582: for(z=0; z<BITS; z++) ! 583: param.b[z] |= bit.b[z]; ! 584: if(v->etype != et || !(MSCALAR&(1<<et))) /* funny punning */ ! 585: for(z=0; z<BITS; z++) ! 586: addrs.b[z] |= bit.b[z]; ! 587: if(t == A_CONST) { ! 588: if(s == ZeroS) { ! 589: for(z=0; z<BITS; z++) ! 590: consts.b[z] |= bit.b[z]; ! 591: return bit; ! 592: } ! 593: if(et != TARRAY) ! 594: for(z=0; z<BITS; z++) ! 595: addrs.b[z] |= bit.b[z]; ! 596: for(z=0; z<BITS; z++) ! 597: param.b[z] |= bit.b[z]; ! 598: return bit; ! 599: } ! 600: if(t == A_INDREG) ! 601: return bit; ! 602: ! 603: none: ! 604: return zbits; ! 605: } ! 606: ! 607: void ! 608: prop(Reg *r, Bits ref, Bits cal) ! 609: { ! 610: Reg *r1, *r2; ! 611: int z; ! 612: ! 613: for(r1 = r; r1 != R; r1 = r1->p1) { ! 614: for(z=0; z<BITS; z++) { ! 615: ref.b[z] |= r1->refahead.b[z]; ! 616: if(ref.b[z] != r1->refahead.b[z]) { ! 617: r1->refahead.b[z] = ref.b[z]; ! 618: change++; ! 619: } ! 620: cal.b[z] |= r1->calahead.b[z]; ! 621: if(cal.b[z] != r1->calahead.b[z]) { ! 622: r1->calahead.b[z] = cal.b[z]; ! 623: change++; ! 624: } ! 625: } ! 626: switch(r1->prog->op) { ! 627: case AJMPL: ! 628: for(z=0; z<BITS; z++) { ! 629: cal.b[z] |= ref.b[z] | externs.b[z]; ! 630: ref.b[z] = 0; ! 631: } ! 632: break; ! 633: ! 634: case ATEXT: ! 635: for(z=0; z<BITS; z++) { ! 636: cal.b[z] = 0; ! 637: ref.b[z] = 0; ! 638: } ! 639: break; ! 640: ! 641: case ARETURN: ! 642: for(z=0; z<BITS; z++) { ! 643: cal.b[z] = externs.b[z]; ! 644: ref.b[z] = 0; ! 645: } ! 646: } ! 647: for(z=0; z<BITS; z++) { ! 648: ref.b[z] = (ref.b[z] & ~r1->set.b[z]) | ! 649: r1->use1.b[z] | r1->use2.b[z]; ! 650: cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]); ! 651: r1->refbehind.b[z] = ref.b[z]; ! 652: r1->calbehind.b[z] = cal.b[z]; ! 653: } ! 654: if(r1->active) ! 655: break; ! 656: r1->active = 1; ! 657: } ! 658: for(; r != r1; r = r->p1) ! 659: for(r2 = r->p2; r2 != R; r2 = r2->p2next) ! 660: prop(r2, r->refbehind, r->calbehind); ! 661: } ! 662: ! 663: int ! 664: loopit(Reg *r) ! 665: { ! 666: Reg *r1; ! 667: int l, m; ! 668: ! 669: l = 0; ! 670: r->active = 1; ! 671: r->loop = 0; ! 672: if(r1 = r->s1) ! 673: switch(r1->active) { ! 674: case 0: ! 675: l += loopit(r1); ! 676: break; ! 677: case 1: ! 678: l += LOOP; ! 679: r1->loop += LOOP; ! 680: } ! 681: if(r1 = r->s2) ! 682: switch(r1->active) { ! 683: case 0: ! 684: l += loopit(r1); ! 685: break; ! 686: case 1: ! 687: l += LOOP; ! 688: r1->loop += LOOP; ! 689: } ! 690: r->active = 2; ! 691: m = r->loop; ! 692: r->loop = l + 1; ! 693: return l - m; ! 694: } ! 695: ! 696: void ! 697: synch(Reg *r, Bits dif) ! 698: { ! 699: Reg *r1; ! 700: int z; ! 701: ! 702: for(r1 = r; r1 != R; r1 = r1->s1) { ! 703: for(z=0; z<BITS; z++) { ! 704: dif.b[z] = (dif.b[z] & ! 705: ~(~r1->refbehind.b[z] & r1->refahead.b[z])) | ! 706: r1->set.b[z] | r1->regdiff.b[z]; ! 707: if(dif.b[z] != r1->regdiff.b[z]) { ! 708: r1->regdiff.b[z] = dif.b[z]; ! 709: change++; ! 710: } ! 711: } ! 712: if(r1->active) ! 713: break; ! 714: r1->active = 1; ! 715: for(z=0; z<BITS; z++) ! 716: dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]); ! 717: if(r1->s2 != R) ! 718: synch(r1->s2, dif); ! 719: } ! 720: } ! 721: ! 722: ulong ! 723: allreg(ulong b, Rgn *r) ! 724: { ! 725: Var *v; ! 726: int i; ! 727: ! 728: v = var + r->varno; ! 729: r->regno = 0; ! 730: switch(v->etype) { ! 731: ! 732: default: ! 733: diag(ZeroN, "unknown etype %d/%d", bitno(b), v->etype); ! 734: break; ! 735: ! 736: case TCHAR: ! 737: case TSINT: ! 738: case TSUINT: ! 739: case TINT: ! 740: case TUINT: ! 741: case TIND: ! 742: case TARRAY: ! 743: i = BtoR(~b); ! 744: if(i && r->cost > 0) { ! 745: r->regno = i; ! 746: return RtoB(i); ! 747: } ! 748: break; ! 749: ! 750: case TFLOAT: ! 751: i = BtoF(~b); ! 752: if(i && r->cost > 0) { ! 753: r->regno = i+Nreg; ! 754: return FtoB(i); ! 755: } ! 756: break; ! 757: } ! 758: return 0; ! 759: } ! 760: ! 761: void ! 762: paint1(Reg *r, int bn) ! 763: { ! 764: Reg *r1; ! 765: Inst *p; ! 766: int z; ! 767: ulong bb; ! 768: ! 769: z = bn/32; ! 770: bb = 1L<<(bn%32); ! 771: if(r->act.b[z] & bb) ! 772: return; ! 773: for(;;) { ! 774: if(!(r->refbehind.b[z] & bb)) ! 775: break; ! 776: r1 = r->p1; ! 777: if(r1 == R) ! 778: break; ! 779: if(!(r1->refahead.b[z] & bb)) ! 780: break; ! 781: if(r1->act.b[z] & bb) ! 782: break; ! 783: r = r1; ! 784: } ! 785: ! 786: if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) { ! 787: change -= CLOAD * r->loop; ! 788: if(opt('R') && opt('v')) ! 789: print("%d%i%|ld %B $%d\n", r->loop, ! 790: r->prog, COL1, blsh(bn), change); ! 791: } ! 792: for(;;) { ! 793: r->act.b[z] |= bb; ! 794: p = r->prog; ! 795: ! 796: if(r->use1.b[z] & bb) { ! 797: change += CREF * r->loop; ! 798: if(p->dst.type == A_FREG && p->op == AMOVW) ! 799: change = -CINF; /* cant go Rreg to Freg */ ! 800: if(opt('R') && opt('v')) ! 801: print("%d%i%|u1 %B $%d\n", r->loop, ! 802: p, COL1, blsh(bn), change); ! 803: } ! 804: ! 805: if((r->use2.b[z]|r->set.b[z]) & bb) { ! 806: change += CREF * r->loop; ! 807: if(p->src1.type == A_FREG && p->op == AMOVW) ! 808: change = -CINF; /* cant go Rreg to Freg */ ! 809: if(opt('R') && opt('v')) ! 810: print("%d%i%|u2 %B $%d\n", r->loop, ! 811: p, COL1, blsh(bn), change); ! 812: } ! 813: ! 814: if(STORE(r) & r->regdiff.b[z] & bb) { ! 815: change -= CLOAD * r->loop; ! 816: if(opt('R') && opt('v')) ! 817: print("%d%i%|st %B $%d\n", r->loop, ! 818: p, COL1, blsh(bn), change); ! 819: } ! 820: ! 821: if(r->refbehind.b[z] & bb) ! 822: for(r1 = r->p2; r1 != R; r1 = r1->p2next) ! 823: if(r1->refahead.b[z] & bb) ! 824: paint1(r1, bn); ! 825: ! 826: if(!(r->refahead.b[z] & bb)) ! 827: break; ! 828: r1 = r->s2; ! 829: if(r1 != R) ! 830: if(r1->refbehind.b[z] & bb) ! 831: paint1(r1, bn); ! 832: r = r->s1; ! 833: if(r == R) ! 834: break; ! 835: if(r->act.b[z] & bb) ! 836: break; ! 837: if(!(r->refbehind.b[z] & bb)) ! 838: break; ! 839: } ! 840: } ! 841: ! 842: ulong ! 843: paint2(Reg *r, int bn) ! 844: { ! 845: Reg *r1; ! 846: int z; ! 847: ulong bb, vreg; ! 848: ! 849: z = bn/32; ! 850: bb = 1L << (bn%32); ! 851: vreg = regbits; ! 852: if(!(r->act.b[z] & bb)) ! 853: return vreg; ! 854: for(;;) { ! 855: if(!(r->refbehind.b[z] & bb)) ! 856: break; ! 857: r1 = r->p1; ! 858: if(r1 == R) ! 859: break; ! 860: if(!(r1->refahead.b[z] & bb)) ! 861: break; ! 862: if(!(r1->act.b[z] & bb)) ! 863: break; ! 864: r = r1; ! 865: } ! 866: for(;;) { ! 867: r->act.b[z] &= ~bb; ! 868: ! 869: vreg |= r->regu; ! 870: ! 871: if(r->refbehind.b[z] & bb) ! 872: for(r1 = r->p2; r1 != R; r1 = r1->p2next) ! 873: if(r1->refahead.b[z] & bb) ! 874: vreg |= paint2(r1, bn); ! 875: ! 876: if(!(r->refahead.b[z] & bb)) ! 877: break; ! 878: r1 = r->s2; ! 879: if(r1 != R) ! 880: if(r1->refbehind.b[z] & bb) ! 881: vreg |= paint2(r1, bn); ! 882: r = r->s1; ! 883: if(r == R) ! 884: break; ! 885: if(!(r->act.b[z] & bb)) ! 886: break; ! 887: if(!(r->refbehind.b[z] & bb)) ! 888: break; ! 889: } ! 890: return vreg; ! 891: } ! 892: ! 893: void ! 894: paint3(Reg *r, int bn, long rb, int rn) ! 895: { ! 896: Reg *r1; ! 897: Inst *p; ! 898: int z; ! 899: ulong bb; ! 900: ! 901: z = bn/32; ! 902: bb = 1L << (bn%32); ! 903: if(r->act.b[z] & bb) ! 904: return; ! 905: for(;;) { ! 906: if(!(r->refbehind.b[z] & bb)) ! 907: break; ! 908: r1 = r->p1; ! 909: if(r1 == R) ! 910: break; ! 911: if(!(r1->refahead.b[z] & bb)) ! 912: break; ! 913: if(r1->act.b[z] & bb) ! 914: break; ! 915: r = r1; ! 916: } ! 917: ! 918: if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) ! 919: addmove(r, bn, rn, 0); ! 920: for(;;) { ! 921: r->act.b[z] |= bb; ! 922: p = r->prog; ! 923: ! 924: if(r->use1.b[z] & bb) { ! 925: if(opt('R')) ! 926: print("%i", p); ! 927: addreg(&p->src1, rn); ! 928: if(opt('R')) ! 929: print("%|.c%i\n", COL1, p); ! 930: } ! 931: if((r->use2.b[z]|r->set.b[z]) & bb) { ! 932: if(opt('R')) ! 933: print("%i", p); ! 934: addreg(&p->dst, rn); ! 935: if(opt('R')) ! 936: print("%|.c%i\n", COL1, p); ! 937: } ! 938: ! 939: if(STORE(r) & r->regdiff.b[z] & bb) ! 940: addmove(r, bn, rn, 1); ! 941: r->regu |= rb; ! 942: ! 943: if(r->refbehind.b[z] & bb) ! 944: for(r1 = r->p2; r1 != R; r1 = r1->p2next) ! 945: if(r1->refahead.b[z] & bb) ! 946: paint3(r1, bn, rb, rn); ! 947: ! 948: if(!(r->refahead.b[z] & bb)) ! 949: break; ! 950: r1 = r->s2; ! 951: if(r1 != R) ! 952: if(r1->refbehind.b[z] & bb) ! 953: paint3(r1, bn, rb, rn); ! 954: r = r->s1; ! 955: if(r == R) ! 956: break; ! 957: if(r->act.b[z] & bb) ! 958: break; ! 959: if(!(r->refbehind.b[z] & bb)) ! 960: break; ! 961: } ! 962: } ! 963: ! 964: void ! 965: addreg(Adres *a, int rn) ! 966: { ! 967: a->sym = 0; ! 968: a->type = A_REG; ! 969: a->class = 0; ! 970: a->reg = rn; ! 971: if(rn >= Nreg) { ! 972: a->type = A_FREG; ! 973: a->reg = rn-Nreg; ! 974: } ! 975: } ! 976: ! 977: /* ! 978: * bit reg ! 979: * 0 R9 ! 980: * 1 R10 ! 981: * ... ... ! 982: * 4 R13 ! 983: * 5 R16 ! 984: * ... ... ! 985: * 20 R31 ! 986: */ ! 987: long ! 988: RtoB(int r) ! 989: { ! 990: ! 991: if(r >= 9 && r <= 13) ! 992: return 1L << (r-9); ! 993: if(r >= 16 && r <= 31) ! 994: return 1L << (r-11); ! 995: return 0; ! 996: } ! 997: ! 998: int ! 999: BtoR(long b) ! 1000: { ! 1001: int r; ! 1002: ! 1003: b &= 0x001fffffL; ! 1004: if(b == 0) ! 1005: return 0; ! 1006: r = bitno(b) + 9; ! 1007: if(r >= 14) ! 1008: r += 2; ! 1009: return r; ! 1010: } ! 1011: ! 1012: /* ! 1013: * bit reg ! 1014: * 22 F4 ! 1015: * 23 F6 ! 1016: * ... ... ! 1017: * 31 F22 ! 1018: */ ! 1019: long ! 1020: FtoB(int f) ! 1021: { ! 1022: ! 1023: if(f < 4 || f > 22 || (f&1)) ! 1024: return 0; ! 1025: return 1L << (f/2 + 20); ! 1026: } ! 1027: ! 1028: BtoF(long b) ! 1029: { ! 1030: ! 1031: b &= 0xffc00000L; ! 1032: if(b == 0) ! 1033: return 0; ! 1034: return bitno(b)*2 - 40; ! 1035: } ! 1036: ! 1037: int ! 1038: bany(Bits *a) ! 1039: { ! 1040: int i; ! 1041: ! 1042: for(i=0; i<BITS; i++) ! 1043: if(a->b[i]) ! 1044: return 1; ! 1045: return 0; ! 1046: } ! 1047: ! 1048: int ! 1049: bnum(Bits a) ! 1050: { ! 1051: int i; ! 1052: long b; ! 1053: ! 1054: for(i=0; i<BITS; i++) ! 1055: if(b = a.b[i]) ! 1056: return 32*i + bitno(b); ! 1057: diag(ZeroN, "bad in bnum"); ! 1058: return 0; ! 1059: } ! 1060: ! 1061: Bits ! 1062: blsh(int n) ! 1063: { ! 1064: Bits c; ! 1065: ! 1066: c = zbits; ! 1067: c.b[n/32] = 1L << (n%32); ! 1068: return c; ! 1069: } ! 1070: ! 1071: int ! 1072: Bconv(void *o, Fconv *f) ! 1073: { ! 1074: char str[128], ss[128], *s; ! 1075: Bits bits; ! 1076: int i; ! 1077: ! 1078: str[0] = 0; ! 1079: bits = *(Bits*)o; ! 1080: while(bany(&bits)) { ! 1081: i = bnum(bits); ! 1082: if(str[0]) ! 1083: strcat(str, " "); ! 1084: if(var[i].sym == ZeroS) { ! 1085: sprint(ss, "$%ld", var[i].ival); ! 1086: s = ss; ! 1087: } else ! 1088: s = var[i].sym->name; ! 1089: if(strlen(str) + strlen(s) + 1 >= 128) ! 1090: break; ! 1091: strcat(str, s); ! 1092: bits.b[i/32] &= ~(1L << (i%32)); ! 1093: } ! 1094: strconv(str, f); ! 1095: return sizeof(bits); ! 1096: } ! 1097: ! 1098: int ! 1099: bitno(long b) ! 1100: { ! 1101: int i; ! 1102: ! 1103: for(i=0; i<32; i++) ! 1104: if(b & (1L<<i)) ! 1105: return i; ! 1106: diag(ZeroN, "bad in bitno"); ! 1107: return 0; ! 1108: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.