diff options
Diffstat (limited to 'src/cmd/8g/reg.c')
-rw-r--r-- | src/cmd/8g/reg.c | 141 |
1 files changed, 56 insertions, 85 deletions
diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c index 302b273a1..13beaf941 100644 --- a/src/cmd/8g/reg.c +++ b/src/cmd/8g/reg.c @@ -34,7 +34,7 @@ #include "opt.h" #define NREGVAR 16 /* 8 integer + 8 floating */ -#define REGBITS ((uint32)0xffff) +#define REGBITS ((uint64)0xffffull) /*c2go enum { NREGVAR = 16, REGBITS = (1<<NREGVAR) - 1, @@ -71,7 +71,7 @@ setaddrs(Bits bit) i = bnum(bit); node = var[i].node; n = var[i].name; - bit.b[i/32] &= ~(1L<<(i%32)); + biclr(&bit, i); // disable all pieces of that variable for(i=0; i<nvar; i++) { @@ -336,7 +336,7 @@ loop2: rgp->varno = i; change = 0; paint1(r, i); - bit.b[i/32] &= ~(1L<<(i%32)); + biclr(&bit, i); if(change <= 0) continue; rgp->cost = change; @@ -358,18 +358,19 @@ brk: * replace code (paint3) */ rgp = region; + if(debug['R'] && debug['v']) + print("\nregisterizing\n"); for(i=0; i<nregion; i++) { + if(debug['R'] && debug['v']) + print("region %d: cost %d varno %d enter %d\n", i, rgp->cost, rgp->varno, rgp->enter->f.prog->pc); bit = blsh(rgp->varno); - vreg = paint2(rgp->enter, rgp->varno); + vreg = paint2(rgp->enter, rgp->varno, 0); vreg = allreg(vreg, rgp); if(rgp->regno != 0) paint3(rgp->enter, rgp->varno, vreg, rgp->regno); rgp++; } - if(debug['R'] && debug['v']) - dumpit("pass6", &firstr->f, 1); - /* * free aux structures. peep allocates new ones. */ @@ -378,6 +379,15 @@ brk: flowend(g); firstr = R; + if(debug['R'] && debug['v']) { + // Rebuild flow graph, since we inserted instructions + g = flowstart(firstp, sizeof(Reg)); + firstr = (Reg*)g->start; + dumpit("pass6", &firstr->f, 1); + flowend(g); + firstr = R; + } + /* * pass 7 * peep-hole on basic block @@ -446,7 +456,7 @@ walkvardef(Node *n, Reg *r, int active) break; for(v=n->opt; v!=nil; v=v->nextinnode) { bn = v - var; - r1->act.b[bn/32] |= 1L << (bn%32); + biset(&r1->act, bn); } if(r1->f.prog->as == ACALL) break; @@ -788,10 +798,10 @@ prop(Reg *r, Bits ref, Bits cal) for(z=0; z<BITS; z++) { if(cal.b[z] == 0) continue; - for(i=0; i<32; i++) { - if(z*32+i >= nvar || ((cal.b[z]>>i)&1) == 0) + for(i=0; i<64; i++) { + if(z*64+i >= nvar || ((cal.b[z]>>i)&1) == 0) continue; - v = var+z*32+i; + v = var+z*64+i; if(v->node->opt == nil) // v represents fixed register, not Go variable continue; @@ -807,10 +817,10 @@ prop(Reg *r, Bits ref, Bits cal) // This will set the bits at most twice, keeping the overall loop linear. v1 = v->node->opt; j = v1 - var; - if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) { + if(v == v1 || !btest(&cal, j)) { for(; v1 != nil; v1 = v1->nextinnode) { j = v1 - var; - cal.b[j/32] |= 1<<(j&31); + biset(&cal, j); } } } @@ -926,10 +936,10 @@ paint1(Reg *r, int bn) Reg *r1; Prog *p; int z; - uint32 bb; + uint64 bb, rbz; - z = bn/32; - bb = 1L<<(bn%32); + z = bn/64; + bb = 1LL<<(bn%64); if(r->act.b[z] & bb) return; for(;;) { @@ -945,7 +955,8 @@ paint1(Reg *r, int bn) r = r1; } - if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) { + rbz = ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])); + if(LOAD(r) & rbz & bb) { change -= CLOAD * r->f.loop; } for(;;) { @@ -996,52 +1007,14 @@ paint1(Reg *r, int bn) } uint32 -regset(Reg *r, uint32 bb) -{ - uint32 b, set; - Adr v; - int c; - - set = 0; - v = zprog.from; - while(b = bb & ~(bb-1)) { - v.type = b & 0xFF ? BtoR(b): BtoF(b); - c = copyu(r->f.prog, &v, nil); - if(c == 3) - set |= b; - bb &= ~b; - } - return set; -} - -uint32 -reguse(Reg *r, uint32 bb) -{ - uint32 b, set; - Adr v; - int c; - - set = 0; - v = zprog.from; - while(b = bb & ~(bb-1)) { - v.type = b & 0xFF ? BtoR(b): BtoF(b); - c = copyu(r->f.prog, &v, nil); - if(c == 1 || c == 2 || c == 4) - set |= b; - bb &= ~b; - } - return set; -} - -uint32 -paint2(Reg *r, int bn) +paint2(Reg *r, int bn, int depth) { Reg *r1; int z; - uint32 bb, vreg, x; + uint64 bb, vreg; - z = bn/32; - bb = 1L << (bn%32); + z = bn/64; + bb = 1LL << (bn%64); vreg = regbits; if(!(r->act.b[z] & bb)) return vreg; @@ -1058,6 +1031,9 @@ paint2(Reg *r, int bn) r = r1; } for(;;) { + if(debug['R'] && debug['v']) + print(" paint2 %d %P\n", depth, r->f.prog); + r->act.b[z] &= ~bb; vreg |= r->regu; @@ -1065,14 +1041,14 @@ paint2(Reg *r, int bn) if(r->refbehind.b[z] & bb) for(r1 = (Reg*)r->f.p2; r1 != R; r1 = (Reg*)r1->f.p2link) if(r1->refahead.b[z] & bb) - vreg |= paint2(r1, bn); + vreg |= paint2(r1, bn, depth+1); if(!(r->refahead.b[z] & bb)) break; r1 = (Reg*)r->f.s2; if(r1 != R) if(r1->refbehind.b[z] & bb) - vreg |= paint2(r1, bn); + vreg |= paint2(r1, bn, depth+1); r = (Reg*)r->f.s1; if(r == R) break; @@ -1082,27 +1058,19 @@ paint2(Reg *r, int bn) break; } - bb = vreg; - for(; r; r=(Reg*)r->f.s1) { - x = r->regu & ~bb; - if(x) { - vreg |= reguse(r, x); - bb |= regset(r, x); - } - } return vreg; } void -paint3(Reg *r, int bn, int32 rb, int rn) +paint3(Reg *r, int bn, uint32 rb, int rn) { Reg *r1; Prog *p; int z; - uint32 bb; + uint64 bb, rbz; - z = bn/32; - bb = 1L << (bn%32); + z = bn/64; + bb = 1LL << (bn%64); if(r->act.b[z] & bb) return; for(;;) { @@ -1118,7 +1086,8 @@ paint3(Reg *r, int bn, int32 rb, int rn) r = r1; } - if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) + rbz = ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])); + if(LOAD(r) & rbz & bb) addmove(r, bn, rn, 0); for(;;) { r->act.b[z] |= bb; @@ -1175,7 +1144,7 @@ addreg(Adr *a, int rn) ostats.ncvtreg++; } -int32 +uint32 RtoB(int r) { @@ -1185,7 +1154,7 @@ RtoB(int r) } int -BtoR(int32 b) +BtoR(uint32 b) { b &= 0xffL; @@ -1194,7 +1163,7 @@ BtoR(int32 b) return bitno(b) + D_AX; } -int32 +uint32 FtoB(int f) { if(f < D_X0 || f > D_X7) @@ -1203,7 +1172,7 @@ FtoB(int f) } int -BtoF(int32 b) +BtoF(uint32 b) { b &= 0xFF00L; if(b == 0) @@ -1273,12 +1242,14 @@ dumpit(char *str, Flow *r0, int isreg) print(" %.4ud", (int)r1->prog->pc); print("\n"); } -// r1 = r->s1; -// if(r1 != nil) { -// print(" succ:"); -// for(; r1 != R; r1 = r1->s1) -// print(" %.4ud", (int)r1->prog->pc); -// print("\n"); -// } + // Print successors if it's not just the next one + if(r->s1 != r->link || r->s2 != nil) { + print(" succ:"); + if(r->s1 != nil) + print(" %.4ud", (int)r->s1->prog->pc); + if(r->s2 != nil) + print(" %.4ud", (int)r->s2->prog->pc); + print("\n"); + } } } |