github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/5c/reg.c (about) 1 // Inferno utils/5c/reg.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/5c/reg.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 32 #include "gc.h" 33 34 void addsplits(void); 35 36 Reg* 37 rega(void) 38 { 39 Reg *r; 40 41 r = freer; 42 if(r == R) { 43 r = alloc(sizeof(*r)); 44 } else 45 freer = r->link; 46 47 *r = zreg; 48 return r; 49 } 50 51 int 52 rcmp(const void *a1, const void *a2) 53 { 54 Rgn *p1, *p2; 55 int c1, c2; 56 57 p1 = (Rgn*)a1; 58 p2 = (Rgn*)a2; 59 c1 = p2->cost; 60 c2 = p1->cost; 61 if(c1 -= c2) 62 return c1; 63 return p2->varno - p1->varno; 64 } 65 66 void 67 regopt(Prog *p) 68 { 69 Reg *r, *r1, *r2; 70 Prog *p1; 71 int i, z; 72 int32 initpc, val, npc; 73 uint32 vreg; 74 Bits bit; 75 struct 76 { 77 int32 m; 78 int32 c; 79 Reg* p; 80 } log5[6], *lp; 81 82 firstr = R; 83 lastr = R; 84 nvar = 0; 85 regbits = 0; 86 for(z=0; z<BITS; z++) { 87 externs.b[z] = 0; 88 params.b[z] = 0; 89 consts.b[z] = 0; 90 addrs.b[z] = 0; 91 } 92 93 /* 94 * pass 1 95 * build aux data structure 96 * allocate pcs 97 * find use and set of variables 98 */ 99 val = 5L * 5L * 5L * 5L * 5L; 100 lp = log5; 101 for(i=0; i<5; i++) { 102 lp->m = val; 103 lp->c = 0; 104 lp->p = R; 105 val /= 5L; 106 lp++; 107 } 108 val = 0; 109 for(; p != P; p = p->link) { 110 switch(p->as) { 111 case ADATA: 112 case AGLOBL: 113 case ANAME: 114 case ASIGNAME: 115 case AFUNCDATA: 116 continue; 117 } 118 r = rega(); 119 if(firstr == R) { 120 firstr = r; 121 lastr = r; 122 } else { 123 lastr->link = r; 124 r->p1 = lastr; 125 lastr->s1 = r; 126 lastr = r; 127 } 128 r->prog = p; 129 r->pc = val; 130 val++; 131 132 lp = log5; 133 for(i=0; i<5; i++) { 134 lp->c--; 135 if(lp->c <= 0) { 136 lp->c = lp->m; 137 if(lp->p != R) 138 lp->p->log5 = r; 139 lp->p = r; 140 (lp+1)->c = 0; 141 break; 142 } 143 lp++; 144 } 145 146 r1 = r->p1; 147 if(r1 != R) 148 switch(r1->prog->as) { 149 case ARET: 150 case AB: 151 case ARFE: 152 r->p1 = R; 153 r1->s1 = R; 154 } 155 156 /* 157 * left side always read 158 */ 159 bit = mkvar(&p->from, p->as==AMOVW); 160 for(z=0; z<BITS; z++) 161 r->use1.b[z] |= bit.b[z]; 162 163 /* 164 * right side depends on opcode 165 */ 166 bit = mkvar(&p->to, 0); 167 if(bany(&bit)) 168 switch(p->as) { 169 default: 170 diag(Z, "reg: unknown asop: %A", p->as); 171 break; 172 173 /* 174 * right side write 175 */ 176 case ANOP: 177 case AMOVB: 178 case AMOVBS: 179 case AMOVBU: 180 case AMOVH: 181 case AMOVHS: 182 case AMOVHU: 183 case AMOVW: 184 case AMOVF: 185 case AMOVD: 186 for(z=0; z<BITS; z++) 187 r->set.b[z] |= bit.b[z]; 188 break; 189 190 /* 191 * right side read 192 */ 193 case APLD: 194 for(z=0; z<BITS; z++) 195 r->use2.b[z] |= bit.b[z]; 196 break; 197 198 /* 199 * funny 200 */ 201 case ABL: 202 for(z=0; z<BITS; z++) 203 addrs.b[z] |= bit.b[z]; 204 break; 205 } 206 207 if(p->as == AMOVM) { 208 if(p->from.type == D_CONST) 209 z = p->from.offset; 210 else 211 z = p->to.offset; 212 for(i=0; z; i++) { 213 if(z&1) 214 regbits |= RtoB(i); 215 z >>= 1; 216 } 217 } 218 } 219 if(firstr == R) 220 return; 221 initpc = pc - val; 222 npc = val; 223 224 /* 225 * pass 2 226 * turn branch references to pointers 227 * build back pointers 228 */ 229 for(r = firstr; r != R; r = r->link) { 230 p = r->prog; 231 if(p->to.type == D_BRANCH) { 232 val = p->to.offset - initpc; 233 r1 = firstr; 234 while(r1 != R) { 235 r2 = r1->log5; 236 if(r2 != R && val >= r2->pc) { 237 r1 = r2; 238 continue; 239 } 240 if(r1->pc == val) 241 break; 242 r1 = r1->link; 243 } 244 if(r1 == R) { 245 nearln = p->lineno; 246 diag(Z, "ref not found\n%P", p); 247 continue; 248 } 249 if(r1 == r) { 250 nearln = p->lineno; 251 diag(Z, "ref to self\n%P", p); 252 continue; 253 } 254 r->s2 = r1; 255 r->p2link = r1->p2; 256 r1->p2 = r; 257 } 258 } 259 if(debug['R']) { 260 p = firstr->prog; 261 print("\n%L %D\n", p->lineno, &p->from); 262 } 263 264 /* 265 * pass 2.5 266 * find looping structure 267 */ 268 for(r = firstr; r != R; r = r->link) 269 r->active = 0; 270 change = 0; 271 loopit(firstr, npc); 272 273 /* 274 * pass 3 275 * iterate propagating usage 276 * back until flow graph is complete 277 */ 278 loop1: 279 change = 0; 280 for(r = firstr; r != R; r = r->link) 281 r->active = 0; 282 for(r = firstr; r != R; r = r->link) 283 if(r->prog->as == ARET) 284 prop(r, zbits, zbits); 285 loop11: 286 /* pick up unreachable code */ 287 i = 0; 288 for(r = firstr; r != R; r = r1) { 289 r1 = r->link; 290 if(r1 && r1->active && !r->active) { 291 prop(r, zbits, zbits); 292 i = 1; 293 } 294 } 295 if(i) 296 goto loop11; 297 if(change) 298 goto loop1; 299 300 301 /* 302 * pass 4 303 * iterate propagating register/variable synchrony 304 * forward until graph is complete 305 */ 306 loop2: 307 change = 0; 308 for(r = firstr; r != R; r = r->link) 309 r->active = 0; 310 synch(firstr, zbits); 311 if(change) 312 goto loop2; 313 314 addsplits(); 315 316 if(debug['R'] && debug['v']) { 317 print("\nprop structure:\n"); 318 for(r = firstr; r != R; r = r->link) { 319 print("%d:%P", r->loop, r->prog); 320 for(z=0; z<BITS; z++) 321 bit.b[z] = r->set.b[z] | 322 r->refahead.b[z] | r->calahead.b[z] | 323 r->refbehind.b[z] | r->calbehind.b[z] | 324 r->use1.b[z] | r->use2.b[z]; 325 if(bany(&bit)) { 326 print("\t"); 327 if(bany(&r->use1)) 328 print(" u1=%B", r->use1); 329 if(bany(&r->use2)) 330 print(" u2=%B", r->use2); 331 if(bany(&r->set)) 332 print(" st=%B", r->set); 333 if(bany(&r->refahead)) 334 print(" ra=%B", r->refahead); 335 if(bany(&r->calahead)) 336 print(" ca=%B", r->calahead); 337 if(bany(&r->refbehind)) 338 print(" rb=%B", r->refbehind); 339 if(bany(&r->calbehind)) 340 print(" cb=%B", r->calbehind); 341 } 342 print("\n"); 343 } 344 } 345 346 /* 347 * pass 5 348 * isolate regions 349 * calculate costs (paint1) 350 */ 351 r = firstr; 352 if(r) { 353 for(z=0; z<BITS; z++) 354 bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & 355 ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]); 356 if(bany(&bit)) { 357 nearln = r->prog->lineno; 358 warn(Z, "used and not set: %B", bit); 359 if(debug['R'] && !debug['w']) 360 print("used and not set: %B\n", bit); 361 } 362 } 363 364 for(r = firstr; r != R; r = r->link) 365 r->act = zbits; 366 rgp = region; 367 nregion = 0; 368 for(r = firstr; r != R; r = r->link) { 369 for(z=0; z<BITS; z++) 370 bit.b[z] = r->set.b[z] & 371 ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]); 372 if(bany(&bit)) { 373 nearln = r->prog->lineno; 374 warn(Z, "set and not used: %B", bit); 375 if(debug['R']) 376 print("set and not used: %B\n", bit); 377 excise(r); 378 } 379 for(z=0; z<BITS; z++) 380 bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]); 381 while(bany(&bit)) { 382 i = bnum(bit); 383 rgp->enter = r; 384 rgp->varno = i; 385 change = 0; 386 if(debug['R'] && debug['v']) 387 print("\n"); 388 paint1(r, i); 389 bit.b[i/32] &= ~(1L<<(i%32)); 390 if(change <= 0) { 391 if(debug['R']) 392 print("%L $%d: %B\n", 393 r->prog->lineno, change, blsh(i)); 394 continue; 395 } 396 rgp->cost = change; 397 nregion++; 398 if(nregion >= NRGN) { 399 warn(Z, "too many regions"); 400 goto brk; 401 } 402 rgp++; 403 } 404 } 405 brk: 406 qsort(region, nregion, sizeof(region[0]), rcmp); 407 408 /* 409 * pass 6 410 * determine used registers (paint2) 411 * replace code (paint3) 412 */ 413 rgp = region; 414 for(i=0; i<nregion; i++) { 415 bit = blsh(rgp->varno); 416 vreg = paint2(rgp->enter, rgp->varno); 417 vreg = allreg(vreg, rgp); 418 if(debug['R']) { 419 if(rgp->regno >= NREG) 420 print("%L $%d F%d: %B\n", 421 rgp->enter->prog->lineno, 422 rgp->cost, 423 rgp->regno-NREG, 424 bit); 425 else 426 print("%L $%d R%d: %B\n", 427 rgp->enter->prog->lineno, 428 rgp->cost, 429 rgp->regno, 430 bit); 431 } 432 if(rgp->regno != 0) 433 paint3(rgp->enter, rgp->varno, vreg, rgp->regno); 434 rgp++; 435 } 436 /* 437 * pass 7 438 * peep-hole on basic block 439 */ 440 if(!debug['R'] || debug['P']) 441 peep(); 442 443 /* 444 * pass 8 445 * recalculate pc 446 */ 447 val = initpc; 448 for(r = firstr; r != R; r = r1) { 449 r->pc = val; 450 p = r->prog; 451 p1 = P; 452 r1 = r->link; 453 if(r1 != R) 454 p1 = r1->prog; 455 for(; p != p1; p = p->link) { 456 switch(p->as) { 457 default: 458 val++; 459 break; 460 461 case ANOP: 462 case ADATA: 463 case AGLOBL: 464 case ANAME: 465 case ASIGNAME: 466 case AFUNCDATA: 467 break; 468 } 469 } 470 } 471 pc = val; 472 473 /* 474 * fix up branches 475 */ 476 if(debug['R']) 477 if(bany(&addrs)) 478 print("addrs: %B\n", addrs); 479 480 r1 = 0; /* set */ 481 for(r = firstr; r != R; r = r->link) { 482 p = r->prog; 483 if(p->to.type == D_BRANCH) 484 p->to.offset = r->s2->pc; 485 r1 = r; 486 } 487 488 /* 489 * last pass 490 * eliminate nops 491 * free aux structures 492 */ 493 for(p = firstr->prog; p != P; p = p->link){ 494 while(p->link && p->link->as == ANOP) 495 p->link = p->link->link; 496 } 497 if(r1 != R) { 498 r1->link = freer; 499 freer = firstr; 500 } 501 } 502 503 void 504 addsplits(void) 505 { 506 Reg *r, *r1; 507 int z, i; 508 Bits bit; 509 510 for(r = firstr; r != R; r = r->link) { 511 if(r->loop > 1) 512 continue; 513 if(r->prog->as == ABL) 514 continue; 515 for(r1 = r->p2; r1 != R; r1 = r1->p2link) { 516 if(r1->loop <= 1) 517 continue; 518 for(z=0; z<BITS; z++) 519 bit.b[z] = r1->calbehind.b[z] & 520 (r->refahead.b[z] | r->use1.b[z] | r->use2.b[z]) & 521 ~(r->calahead.b[z] & addrs.b[z]); 522 while(bany(&bit)) { 523 i = bnum(bit); 524 bit.b[i/32] &= ~(1L << (i%32)); 525 } 526 } 527 } 528 } 529 530 /* 531 * add mov b,rn 532 * just after r 533 */ 534 void 535 addmove(Reg *r, int bn, int rn, int f) 536 { 537 Prog *p, *p1; 538 Adr *a; 539 Var *v; 540 541 p1 = alloc(sizeof(*p1)); 542 *p1 = zprog; 543 p = r->prog; 544 545 p1->link = p->link; 546 p->link = p1; 547 p1->lineno = p->lineno; 548 549 v = var + bn; 550 551 a = &p1->to; 552 a->sym = v->sym; 553 a->name = v->name; 554 a->offset = v->offset; 555 a->etype = v->etype; 556 a->type = D_OREG; 557 if(a->etype == TARRAY || a->sym == S) 558 a->type = D_CONST; 559 560 p1->as = AMOVW; 561 if(v->etype == TCHAR || v->etype == TUCHAR) 562 p1->as = AMOVBS; 563 if(v->etype == TSHORT || v->etype == TUSHORT) 564 p1->as = AMOVHS; 565 if(v->etype == TFLOAT) 566 p1->as = AMOVF; 567 if(v->etype == TDOUBLE) 568 p1->as = AMOVD; 569 570 p1->from.type = D_REG; 571 p1->from.reg = rn; 572 if(rn >= NREG) { 573 p1->from.type = D_FREG; 574 p1->from.reg = rn-NREG; 575 } 576 if(!f) { 577 p1->from = *a; 578 *a = zprog.from; 579 a->type = D_REG; 580 a->reg = rn; 581 if(rn >= NREG) { 582 a->type = D_FREG; 583 a->reg = rn-NREG; 584 } 585 if(v->etype == TUCHAR) 586 p1->as = AMOVBU; 587 if(v->etype == TUSHORT) 588 p1->as = AMOVHU; 589 } 590 if(debug['R']) 591 print("%P\t.a%P\n", p, p1); 592 } 593 594 Bits 595 mkvar(Adr *a, int docon) 596 { 597 Var *v; 598 int i, t, n, et, z; 599 int32 o; 600 Bits bit; 601 Sym *s; 602 603 t = a->type; 604 if(t == D_REG && a->reg != NREG) 605 regbits |= RtoB(a->reg); 606 if(t == D_FREG && a->reg != NREG) 607 regbits |= FtoB(a->reg); 608 s = a->sym; 609 o = a->offset; 610 et = a->etype; 611 if(s == S) { 612 if(t != D_CONST || !docon || a->reg != NREG) 613 goto none; 614 et = TLONG; 615 } 616 if(t == D_CONST) { 617 if(s == S && sval(o)) 618 goto none; 619 } 620 621 n = a->name; 622 v = var; 623 for(i=0; i<nvar; i++) { 624 if(s == v->sym) 625 if(n == v->name) 626 if(o == v->offset) 627 goto out; 628 v++; 629 } 630 if(s) 631 if(s->name[0] == '.') 632 goto none; 633 if(nvar >= NVAR) { 634 if(debug['w'] > 1 && s) 635 warn(Z, "variable not optimized: %s", s->name); 636 goto none; 637 } 638 i = nvar; 639 nvar++; 640 v = &var[i]; 641 v->sym = s; 642 v->offset = o; 643 v->etype = et; 644 v->name = n; 645 if(debug['R']) 646 print("bit=%2d et=%2d %D\n", i, et, a); 647 out: 648 bit = blsh(i); 649 if(n == D_EXTERN || n == D_STATIC) 650 for(z=0; z<BITS; z++) 651 externs.b[z] |= bit.b[z]; 652 if(n == D_PARAM) 653 for(z=0; z<BITS; z++) 654 params.b[z] |= bit.b[z]; 655 if(v->etype != et || !typechlpfd[et]) /* funny punning */ 656 for(z=0; z<BITS; z++) 657 addrs.b[z] |= bit.b[z]; 658 if(t == D_CONST) { 659 if(s == S) { 660 for(z=0; z<BITS; z++) 661 consts.b[z] |= bit.b[z]; 662 return bit; 663 } 664 if(et != TARRAY) 665 for(z=0; z<BITS; z++) 666 addrs.b[z] |= bit.b[z]; 667 for(z=0; z<BITS; z++) 668 params.b[z] |= bit.b[z]; 669 return bit; 670 } 671 if(t == D_OREG) 672 return bit; 673 674 none: 675 return zbits; 676 } 677 678 void 679 prop(Reg *r, Bits ref, Bits cal) 680 { 681 Reg *r1, *r2; 682 int z; 683 684 for(r1 = r; r1 != R; r1 = r1->p1) { 685 for(z=0; z<BITS; z++) { 686 ref.b[z] |= r1->refahead.b[z]; 687 if(ref.b[z] != r1->refahead.b[z]) { 688 r1->refahead.b[z] = ref.b[z]; 689 change++; 690 } 691 cal.b[z] |= r1->calahead.b[z]; 692 if(cal.b[z] != r1->calahead.b[z]) { 693 r1->calahead.b[z] = cal.b[z]; 694 change++; 695 } 696 } 697 switch(r1->prog->as) { 698 case ABL: 699 for(z=0; z<BITS; z++) { 700 cal.b[z] |= ref.b[z] | externs.b[z]; 701 ref.b[z] = 0; 702 } 703 break; 704 705 case ATEXT: 706 for(z=0; z<BITS; z++) { 707 cal.b[z] = 0; 708 ref.b[z] = 0; 709 } 710 break; 711 712 case ARET: 713 for(z=0; z<BITS; z++) { 714 cal.b[z] = externs.b[z]; 715 ref.b[z] = 0; 716 } 717 } 718 for(z=0; z<BITS; z++) { 719 ref.b[z] = (ref.b[z] & ~r1->set.b[z]) | 720 r1->use1.b[z] | r1->use2.b[z]; 721 cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]); 722 r1->refbehind.b[z] = ref.b[z]; 723 r1->calbehind.b[z] = cal.b[z]; 724 } 725 if(r1->active) 726 break; 727 r1->active = 1; 728 } 729 for(; r != r1; r = r->p1) 730 for(r2 = r->p2; r2 != R; r2 = r2->p2link) 731 prop(r2, r->refbehind, r->calbehind); 732 } 733 734 /* 735 * find looping structure 736 * 737 * 1) find reverse postordering 738 * 2) find approximate dominators, 739 * the actual dominators if the flow graph is reducible 740 * otherwise, dominators plus some other non-dominators. 741 * See Matthew S. Hecht and Jeffrey D. Ullman, 742 * "Analysis of a Simple Algorithm for Global Data Flow Problems", 743 * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts, 744 * Oct. 1-3, 1973, pp. 207-217. 745 * 3) find all nodes with a predecessor dominated by the current node. 746 * such a node is a loop head. 747 * recursively, all preds with a greater rpo number are in the loop 748 */ 749 int32 750 postorder(Reg *r, Reg **rpo2r, int32 n) 751 { 752 Reg *r1; 753 754 r->rpo = 1; 755 r1 = r->s1; 756 if(r1 && !r1->rpo) 757 n = postorder(r1, rpo2r, n); 758 r1 = r->s2; 759 if(r1 && !r1->rpo) 760 n = postorder(r1, rpo2r, n); 761 rpo2r[n] = r; 762 n++; 763 return n; 764 } 765 766 int32 767 rpolca(int32 *idom, int32 rpo1, int32 rpo2) 768 { 769 int32 t; 770 771 if(rpo1 == -1) 772 return rpo2; 773 while(rpo1 != rpo2){ 774 if(rpo1 > rpo2){ 775 t = rpo2; 776 rpo2 = rpo1; 777 rpo1 = t; 778 } 779 while(rpo1 < rpo2){ 780 t = idom[rpo2]; 781 if(t >= rpo2) 782 fatal(Z, "bad idom"); 783 rpo2 = t; 784 } 785 } 786 return rpo1; 787 } 788 789 int 790 doms(int32 *idom, int32 r, int32 s) 791 { 792 while(s > r) 793 s = idom[s]; 794 return s == r; 795 } 796 797 int 798 loophead(int32 *idom, Reg *r) 799 { 800 int32 src; 801 802 src = r->rpo; 803 if(r->p1 != R && doms(idom, src, r->p1->rpo)) 804 return 1; 805 for(r = r->p2; r != R; r = r->p2link) 806 if(doms(idom, src, r->rpo)) 807 return 1; 808 return 0; 809 } 810 811 void 812 loopmark(Reg **rpo2r, int32 head, Reg *r) 813 { 814 if(r->rpo < head || r->active == head) 815 return; 816 r->active = head; 817 r->loop += LOOP; 818 if(r->p1 != R) 819 loopmark(rpo2r, head, r->p1); 820 for(r = r->p2; r != R; r = r->p2link) 821 loopmark(rpo2r, head, r); 822 } 823 824 void 825 loopit(Reg *r, int32 nr) 826 { 827 Reg *r1; 828 int32 i, d, me; 829 830 if(nr > maxnr) { 831 rpo2r = alloc(nr * sizeof(Reg*)); 832 idom = alloc(nr * sizeof(int32)); 833 maxnr = nr; 834 } 835 d = postorder(r, rpo2r, 0); 836 if(d > nr) 837 fatal(Z, "too many reg nodes"); 838 nr = d; 839 for(i = 0; i < nr / 2; i++){ 840 r1 = rpo2r[i]; 841 rpo2r[i] = rpo2r[nr - 1 - i]; 842 rpo2r[nr - 1 - i] = r1; 843 } 844 for(i = 0; i < nr; i++) 845 rpo2r[i]->rpo = i; 846 847 idom[0] = 0; 848 for(i = 0; i < nr; i++){ 849 r1 = rpo2r[i]; 850 me = r1->rpo; 851 d = -1; 852 if(r1->p1 != R && r1->p1->rpo < me) 853 d = r1->p1->rpo; 854 for(r1 = r1->p2; r1 != nil; r1 = r1->p2link) 855 if(r1->rpo < me) 856 d = rpolca(idom, d, r1->rpo); 857 idom[i] = d; 858 } 859 860 for(i = 0; i < nr; i++){ 861 r1 = rpo2r[i]; 862 r1->loop++; 863 if(r1->p2 != R && loophead(idom, r1)) 864 loopmark(rpo2r, i, r1); 865 } 866 } 867 868 void 869 synch(Reg *r, Bits dif) 870 { 871 Reg *r1; 872 int z; 873 874 for(r1 = r; r1 != R; r1 = r1->s1) { 875 for(z=0; z<BITS; z++) { 876 dif.b[z] = (dif.b[z] & 877 ~(~r1->refbehind.b[z] & r1->refahead.b[z])) | 878 r1->set.b[z] | r1->regdiff.b[z]; 879 if(dif.b[z] != r1->regdiff.b[z]) { 880 r1->regdiff.b[z] = dif.b[z]; 881 change++; 882 } 883 } 884 if(r1->active) 885 break; 886 r1->active = 1; 887 for(z=0; z<BITS; z++) 888 dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]); 889 if(r1->s2 != R) 890 synch(r1->s2, dif); 891 } 892 } 893 894 uint32 895 allreg(uint32 b, Rgn *r) 896 { 897 Var *v; 898 int i; 899 900 v = var + r->varno; 901 r->regno = 0; 902 switch(v->etype) { 903 904 default: 905 diag(Z, "unknown etype %d/%d", bitno(b), v->etype); 906 break; 907 908 case TCHAR: 909 case TUCHAR: 910 case TSHORT: 911 case TUSHORT: 912 case TINT: 913 case TUINT: 914 case TLONG: 915 case TULONG: 916 case TIND: 917 case TARRAY: 918 i = BtoR(~b); 919 if(i && r->cost >= 0) { 920 r->regno = i; 921 return RtoB(i); 922 } 923 break; 924 925 case TVLONG: 926 case TDOUBLE: 927 case TFLOAT: 928 i = BtoF(~b); 929 if(i && r->cost >= 0) { 930 r->regno = i+NREG; 931 return FtoB(i); 932 } 933 break; 934 } 935 return 0; 936 } 937 938 void 939 paint1(Reg *r, int bn) 940 { 941 Reg *r1; 942 Prog *p; 943 int z; 944 uint32 bb; 945 946 z = bn/32; 947 bb = 1L<<(bn%32); 948 if(r->act.b[z] & bb) 949 return; 950 for(;;) { 951 if(!(r->refbehind.b[z] & bb)) 952 break; 953 r1 = r->p1; 954 if(r1 == R) 955 break; 956 if(!(r1->refahead.b[z] & bb)) 957 break; 958 if(r1->act.b[z] & bb) 959 break; 960 r = r1; 961 } 962 963 if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) { 964 change -= CLOAD * r->loop; 965 if(debug['R'] && debug['v']) 966 print("%d%P\td %B $%d\n", r->loop, 967 r->prog, blsh(bn), change); 968 } 969 for(;;) { 970 r->act.b[z] |= bb; 971 p = r->prog; 972 973 if(r->use1.b[z] & bb) { 974 change += CREF * r->loop; 975 if(debug['R'] && debug['v']) 976 print("%d%P\tu1 %B $%d\n", r->loop, 977 p, blsh(bn), change); 978 } 979 980 if((r->use2.b[z]|r->set.b[z]) & bb) { 981 change += CREF * r->loop; 982 if(debug['R'] && debug['v']) 983 print("%d%P\tu2 %B $%d\n", r->loop, 984 p, blsh(bn), change); 985 } 986 987 if(STORE(r) & r->regdiff.b[z] & bb) { 988 change -= CLOAD * r->loop; 989 if(debug['R'] && debug['v']) 990 print("%d%P\tst %B $%d\n", r->loop, 991 p, blsh(bn), change); 992 } 993 994 if(r->refbehind.b[z] & bb) 995 for(r1 = r->p2; r1 != R; r1 = r1->p2link) 996 if(r1->refahead.b[z] & bb) 997 paint1(r1, bn); 998 999 if(!(r->refahead.b[z] & bb)) 1000 break; 1001 r1 = r->s2; 1002 if(r1 != R) 1003 if(r1->refbehind.b[z] & bb) 1004 paint1(r1, bn); 1005 r = r->s1; 1006 if(r == R) 1007 break; 1008 if(r->act.b[z] & bb) 1009 break; 1010 if(!(r->refbehind.b[z] & bb)) 1011 break; 1012 } 1013 } 1014 1015 uint32 1016 paint2(Reg *r, int bn) 1017 { 1018 Reg *r1; 1019 int z; 1020 uint32 bb, vreg; 1021 1022 z = bn/32; 1023 bb = 1L << (bn%32); 1024 vreg = regbits; 1025 if(!(r->act.b[z] & bb)) 1026 return vreg; 1027 for(;;) { 1028 if(!(r->refbehind.b[z] & bb)) 1029 break; 1030 r1 = r->p1; 1031 if(r1 == R) 1032 break; 1033 if(!(r1->refahead.b[z] & bb)) 1034 break; 1035 if(!(r1->act.b[z] & bb)) 1036 break; 1037 r = r1; 1038 } 1039 for(;;) { 1040 r->act.b[z] &= ~bb; 1041 1042 vreg |= r->regu; 1043 1044 if(r->refbehind.b[z] & bb) 1045 for(r1 = r->p2; r1 != R; r1 = r1->p2link) 1046 if(r1->refahead.b[z] & bb) 1047 vreg |= paint2(r1, bn); 1048 1049 if(!(r->refahead.b[z] & bb)) 1050 break; 1051 r1 = r->s2; 1052 if(r1 != R) 1053 if(r1->refbehind.b[z] & bb) 1054 vreg |= paint2(r1, bn); 1055 r = r->s1; 1056 if(r == R) 1057 break; 1058 if(!(r->act.b[z] & bb)) 1059 break; 1060 if(!(r->refbehind.b[z] & bb)) 1061 break; 1062 } 1063 return vreg; 1064 } 1065 1066 void 1067 paint3(Reg *r, int bn, int32 rb, int rn) 1068 { 1069 Reg *r1; 1070 Prog *p; 1071 int z; 1072 uint32 bb; 1073 1074 z = bn/32; 1075 bb = 1L << (bn%32); 1076 if(r->act.b[z] & bb) 1077 return; 1078 for(;;) { 1079 if(!(r->refbehind.b[z] & bb)) 1080 break; 1081 r1 = r->p1; 1082 if(r1 == R) 1083 break; 1084 if(!(r1->refahead.b[z] & bb)) 1085 break; 1086 if(r1->act.b[z] & bb) 1087 break; 1088 r = r1; 1089 } 1090 1091 if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) 1092 addmove(r, bn, rn, 0); 1093 for(;;) { 1094 r->act.b[z] |= bb; 1095 p = r->prog; 1096 1097 if(r->use1.b[z] & bb) { 1098 if(debug['R']) 1099 print("%P", p); 1100 addreg(&p->from, rn); 1101 if(debug['R']) 1102 print("\t.c%P\n", p); 1103 } 1104 if((r->use2.b[z]|r->set.b[z]) & bb) { 1105 if(debug['R']) 1106 print("%P", p); 1107 addreg(&p->to, rn); 1108 if(debug['R']) 1109 print("\t.c%P\n", p); 1110 } 1111 1112 if(STORE(r) & r->regdiff.b[z] & bb) 1113 addmove(r, bn, rn, 1); 1114 r->regu |= rb; 1115 1116 if(r->refbehind.b[z] & bb) 1117 for(r1 = r->p2; r1 != R; r1 = r1->p2link) 1118 if(r1->refahead.b[z] & bb) 1119 paint3(r1, bn, rb, rn); 1120 1121 if(!(r->refahead.b[z] & bb)) 1122 break; 1123 r1 = r->s2; 1124 if(r1 != R) 1125 if(r1->refbehind.b[z] & bb) 1126 paint3(r1, bn, rb, rn); 1127 r = r->s1; 1128 if(r == R) 1129 break; 1130 if(r->act.b[z] & bb) 1131 break; 1132 if(!(r->refbehind.b[z] & bb)) 1133 break; 1134 } 1135 } 1136 1137 void 1138 addreg(Adr *a, int rn) 1139 { 1140 1141 a->sym = 0; 1142 a->name = D_NONE; 1143 a->type = D_REG; 1144 a->reg = rn; 1145 if(rn >= NREG) { 1146 a->type = D_FREG; 1147 a->reg = rn-NREG; 1148 } 1149 } 1150 1151 /* 1152 * bit reg 1153 * 0 R0 1154 * 1 R1 1155 * ... ... 1156 * 10 R10 1157 * 12 R12 1158 */ 1159 int32 1160 RtoB(int r) 1161 { 1162 1163 if(r < 2 || (r >= REGTMP-2 && r != 12)) // excluded R9 and R10 for m and g, but not R12 1164 return 0; 1165 return 1L << r; 1166 } 1167 1168 int 1169 BtoR(int32 b) 1170 { 1171 b &= 0x11fcL; // excluded R9 and R10 for m and g, but not R12 1172 if(b == 0) 1173 return 0; 1174 return bitno(b); 1175 } 1176 1177 /* 1178 * bit reg 1179 * 18 F2 1180 * 19 F3 1181 * ... ... 1182 * 31 F15 1183 */ 1184 int32 1185 FtoB(int f) 1186 { 1187 1188 if(f < 2 || f > NFREG-1) 1189 return 0; 1190 return 1L << (f + 16); 1191 } 1192 1193 int 1194 BtoF(int32 b) 1195 { 1196 1197 b &= 0xfffc0000L; 1198 if(b == 0) 1199 return 0; 1200 return bitno(b) - 16; 1201 }