📄 reg.c
字号:
out: bit = blsh(i); if(t == D_EXTERN || t == D_STATIC) for(z=0; z<BITS; z++) externs.b[z] |= bit.b[z]; if(t == D_PARAM) for(z=0; z<BITS; z++) params.b[z] |= bit.b[z]; if(a->etype != v->etype || !typechlpfd[a->etype]) for(z=0; z<BITS; z++) addrs.b[z] |= bit.b[z]; /* funny punning */ return bit;none: return zbits;}voidprop(Reg *r, Bits ref, Bits cal){ Reg *r1, *r2; int z; for(r1 = r; r1 != R; r1 = r1->p1) { for(z=0; z<BITS; z++) { ref.b[z] |= r1->refahead.b[z]; if(ref.b[z] != r1->refahead.b[z]) { r1->refahead.b[z] = ref.b[z]; changer++; } cal.b[z] |= r1->calahead.b[z]; if(cal.b[z] != r1->calahead.b[z]) { r1->calahead.b[z] = cal.b[z]; changer++; } } switch(r1->prog->as) { case ABSR: for(z=0; z<BITS; z++) { cal.b[z] |= ref.b[z] | externs.b[z]; ref.b[z] = 0; } break; case ATEXT: for(z=0; z<BITS; z++) { cal.b[z] = 0; ref.b[z] = 0; } break; case ARTS: for(z=0; z<BITS; z++) { cal.b[z] = externs.b[z]; ref.b[z] = 0; } } for(z=0; z<BITS; z++) { ref.b[z] = (ref.b[z] & ~r1->set.b[z]) | r1->use1.b[z] | r1->use2.b[z]; cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]); r1->refbehind.b[z] = ref.b[z]; r1->calbehind.b[z] = cal.b[z]; } if(r1->active) break; r1->active = 1; } for(; r != r1; r = r->p1) for(r2 = r->p2; r2 != R; r2 = r2->p2link) prop(r2, r->refbehind, r->calbehind);}/* * find looping structure * * 1) find reverse postordering * 2) find approximate dominators, * the actual dominators if the flow graph is reducible * otherwise, dominators plus some other non-dominators. * See Matthew S. Hecht and Jeffrey D. Ullman, * "Analysis of a Simple Algorithm for Global Data Flow Problems", * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts, * Oct. 1-3, 1973, pp. 207-217. * 3) find all nodes with a predecessor dominated by the current node. * such a node is a loop head. * recursively, all preds with a greater rpo number are in the loop */longpostorder(Reg *r, Reg **rpo2r, long n){ Reg *r1; r->rpo = 1; r1 = r->s1; if(r1 && !r1->rpo) n = postorder(r1, rpo2r, n); r1 = r->s2; if(r1 && !r1->rpo) n = postorder(r1, rpo2r, n); rpo2r[n] = r; n++; return n;}longrpolca(long *idom, long rpo1, long rpo2){ long t; if(rpo1 == -1) return rpo2; while(rpo1 != rpo2){ if(rpo1 > rpo2){ t = rpo2; rpo2 = rpo1; rpo1 = t; } while(rpo1 < rpo2){ t = idom[rpo2]; if(t >= rpo2) fatal(Z, "bad idom"); rpo2 = t; } } return rpo1;}intdoms(long *idom, long r, long s){ while(s > r) s = idom[s]; return s == r;}intloophead(long *idom, Reg *r){ long src; src = r->rpo; if(r->p1 != R && doms(idom, src, r->p1->rpo)) return 1; for(r = r->p2; r != R; r = r->p2link) if(doms(idom, src, r->rpo)) return 1; return 0;}voidloopmark(Reg **rpo2r, long head, Reg *r){ if(r->rpo < head || r->active == head) return; r->active = head; r->loop += LOOP; if(r->p1 != R) loopmark(rpo2r, head, r->p1); for(r = r->p2; r != R; r = r->p2link) loopmark(rpo2r, head, r);}voidloopit(Reg *r, long nr){ Reg *r1; long i, d, me; if(nr > maxnr) { rpo2r = alloc(nr * sizeof(Reg*)); idom = alloc(nr * sizeof(long)); maxnr = nr; } d = postorder(r, rpo2r, 0); if(d > nr) fatal(Z, "too many reg nodes"); nr = d; for(i = 0; i < nr / 2; i++){ r1 = rpo2r[i]; rpo2r[i] = rpo2r[nr - 1 - i]; rpo2r[nr - 1 - i] = r1; } for(i = 0; i < nr; i++) rpo2r[i]->rpo = i; idom[0] = 0; for(i = 0; i < nr; i++){ r1 = rpo2r[i]; me = r1->rpo; d = -1; if(r1->p1 != R && r1->p1->rpo < me) d = r1->p1->rpo; for(r1 = r1->p2; r1 != nil; r1 = r1->p2link) if(r1->rpo < me) d = rpolca(idom, d, r1->rpo); idom[i] = d; } for(i = 0; i < nr; i++){ r1 = rpo2r[i]; r1->loop++; if(r1->p2 != R && loophead(idom, r1)) loopmark(rpo2r, i, r1); }}voidsynch(Reg *r, Bits dif){ Reg *r1; int z; for(r1 = r; r1 != R; r1 = r1->s1) { for(z=0; z<BITS; z++) { dif.b[z] = (dif.b[z] & ~(~r1->refbehind.b[z] & r1->refahead.b[z])) | r1->set.b[z] | r1->regdiff.b[z]; if(dif.b[z] != r1->regdiff.b[z]) { r1->regdiff.b[z] = dif.b[z]; changer++; } } if(r1->active) break; r1->active = 1; for(z=0; z<BITS; z++) dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]); if(r1->s2 != R) synch(r1->s2, dif); }}ulongallreg(ulong b, Rgn *r){ Var *v; int i, j; v = var + r->varno; r->regno = D_NONE; switch(v->etype) { default: diag(Z, "unknown etype"); break; case TCHAR: case TUCHAR: case TSHORT: case TUSHORT: case TINT: case TUINT: case TLONG: case TULONG: case TIND: i = BtoR(~b); j = BtoA(~b); if(r->costa == r->costr) if(i > j) i = NREG; if(j < NREG && r->costa > 0) if(r->costa > r->costr || i >= NREG) { r->regno = D_A0 + j; return AtoB(j); } if(i < NREG && r->costr > 0) { r->regno = D_R0 + i; return RtoB(i); } break; case TDOUBLE: case TFLOAT: i = BtoF(~b); if(i < NREG) { r->regno = D_F0 + i; return FtoB(i); } break; } return 0;}voidpaint1(Reg *r, int bn){ Reg *r1; Prog *p; int z; ulong bb; int x; z = bn/32; bb = 1L<<(bn%32); if(r->act.b[z] & bb) return; for(;;) { if(!(r->refbehind.b[z] & bb)) break; r1 = r->p1; if(r1 == R) break; if(!(r1->refahead.b[z] & bb)) break; if(r1->act.b[z] & bb) break; r = r1; } if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) { changer -= CLOAD * r->loop; changea -= CLOAD * r->loop; if(debug['R'] && debug['v']) print("%ld%P\tld %B $%d.%d\n", r->loop, r->prog, blsh(bn), changer, changea); } for(;;) { r->act.b[z] |= bb; p = r->prog; if(r->use1.b[z] & bb) { changer += CREF * r->loop; changea += CREF * r->loop; x = p->from.index; if(x == D_NONE) { switch(p->as) { default: changea = -CINF; case AADDL: case ASUBL: case AMOVL: case ACMPL: break; } } else { changer += (CXREF-CREF) * r->loop; if(x != (I_INDEX3|D_NONE)) changer = -CINF; if((x&I_MASK) == I_INDEX1) changea = -CINF; } if(p->as == AMOVL) { x = p->to.type; if(x >= D_R0 && x < D_R0+NREG) changer += r->loop; if(x >= D_A0 && x < D_A0+NREG) changea += r->loop; } if(debug['R'] && debug['v']) print("%ld%P\tu1 %B $%d.%d\n", r->loop, p, blsh(bn), changer, changea); } if((r->use2.b[z]|r->set.b[z]) & bb) { changer += CREF * r->loop; changea += CREF * r->loop; x = p->to.index; if(x == D_NONE) switch(p->as) { default: changea = -CINF; break; case AMOVL: case AADDL: case ACMPL: case ASUBL: case ACLRL: /* can be faked */ case ATSTL: /* can be faked */ break; } else { changer += (CXREF-CREF) * r->loop; if(x != (I_INDEX3|D_NONE)) changer = -CINF; if((x&I_MASK) == I_INDEX1) changea = -CINF; } if(p->as == AMOVL) { x = p->from.type; if(x >= D_R0 && x < D_R0+NREG) changer += r->loop; if(x >= D_A0 && x < D_A0+NREG) changea += r->loop; } if(debug['R'] && debug['v']) print("%ld%P\tu2 %B $%d.%d\n", r->loop, p, blsh(bn), changer, changea); } if(STORE(r) & r->regdiff.b[z] & bb) { changer -= CLOAD * r->loop; changea -= CLOAD * r->loop; if(debug['R'] && debug['v']) print("%ld%P\tst %B $%d.%d\n", r->loop, p, blsh(bn), changer, changea); } if(r->refbehind.b[z] & bb) for(r1 = r->p2; r1 != R; r1 = r1->p2link) if(r1->refahead.b[z] & bb) paint1(r1, bn); if(!(r->refahead.b[z] & bb)) break; r1 = r->s2; if(r1 != R) if(r1->refbehind.b[z] & bb) paint1(r1, bn); r = r->s1; if(r == R) break; if(r->act.b[z] & bb) break; if(!(r->refbehind.b[z] & bb)) break; }}ulongpaint2(Reg *r, int bn){ Reg *r1; int z; ulong bb, vreg; z = bn/32; bb = 1L << (bn%32); vreg = regbits; if(!(r->act.b[z] & bb)) return vreg; for(;;) { if(!(r->refbehind.b[z] & bb)) break; r1 = r->p1; if(r1 == R) break; if(!(r1->refahead.b[z] & bb)) break; if(!(r1->act.b[z] & bb)) break; r = r1; } for(;;) { r->act.b[z] &= ~bb; vreg |= r->regu; if(r->refbehind.b[z] & bb) for(r1 = r->p2; r1 != R; r1 = r1->p2link) if(r1->refahead.b[z] & bb) vreg |= paint2(r1, bn); if(!(r->refahead.b[z] & bb)) break; r1 = r->s2; if(r1 != R) if(r1->refbehind.b[z] & bb) vreg |= paint2(r1, bn); r = r->s1; if(r == R) break; if(!(r->act.b[z] & bb)) break; if(!(r->refbehind.b[z] & bb)) break; } return vreg;}voidpaint3(Reg *r, int bn, ulong rb, int rn){ Reg *r1; Prog *p; int z; ulong bb; z = bn/32; bb = 1L << (bn%32); if(r->act.b[z] & bb) return; for(;;) { if(!(r->refbehind.b[z] & bb)) break; r1 = r->p1; if(r1 == R) break; if(!(r1->refahead.b[z] & bb)) break; if(r1->act.b[z] & bb) break; r = r1; } if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) addmove(r, bn, rn, 0); for(;;) { r->act.b[z] |= bb; p = r->prog; if(r->use1.b[z] & bb) { if(debug['R']) print("%P", p); addreg(&p->from, rn); if(debug['R']) print("\t.c%P\n", p); } if((r->use2.b[z]|r->set.b[z]) & bb) { if(debug['R']) print("%P", p); addreg(&p->to, rn); if(debug['R']) print("\t.c%P\n", p); } if(STORE(r) & r->regdiff.b[z] & bb) addmove(r, bn, rn, 1); r->regu |= rb; if(r->refbehind.b[z] & bb) for(r1 = r->p2; r1 != R; r1 = r1->p2link) if(r1->refahead.b[z] & bb) paint3(r1, bn, rb, rn); if(!(r->refahead.b[z] & bb)) break; r1 = r->s2; if(r1 != R) if(r1->refbehind.b[z] & bb) paint3(r1, bn, rb, rn); r = r->s1; if(r == R) break; if(r->act.b[z] & bb) break; if(!(r->refbehind.b[z] & bb)) break; }}voidaddreg(Adr *a, int rn){ int x; a->sym = 0; x = a->index; if(rn >= D_R0 && rn < D_R0+NREG) goto addr; if(x == (I_INDEX3|D_NONE)) { a->type = rn | I_INDIR; a->index = D_NONE; a->offset = a->displace; a->displace = 0; return; } if(x != D_NONE) { a->type = rn | I_INDIR; a->index += I_INDEX1 - I_INDEX2; a->offset = a->displace; a->displace = 0; return; } a->type = rn | (a->type & I_INDIR); return;addr: if(x == (I_INDEX3|D_NONE)) { a->type = D_NONE|I_INDIR; a->index += I_INDEX1 + rn - D_NONE - I_INDEX3; a->scale = 4; /* .L*1 */ a->offset = a->displace; a->displace = 0; return; } a->type = rn | (a->type & I_INDIR);}/* * bit reg * 0-7 R0-R7 * 8-15 A0-A7 * 16-23 F0-F7 */ulongRtoB(int r){ if(r < 0 || r >= NREG) return 0; return 1L << (r + 0);}intBtoR(ulong b){ b &= 0x0000ffL; if(b == 0) return NREG; return bitno(b) - 0;}ulongAtoB(int a){ if(a < 0 || a >= NREG) return 0; return 1L << (a + NREG);}intBtoA(ulong b){ b &= 0x00ff00L; if(b == 0) return NREG; return bitno(b) - NREG;}ulongFtoB(int f){ if(f < 0 || f >= NREG) return 0; return 1L << (f + NREG+NREG);}intBtoF(ulong b){ b &= 0xff0000L; if(b == 0) return NREG; return bitno(b) - NREG-NREG;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -