diff options
author | Russ Cox <rsc@golang.org> | 2014-12-05 11:43:41 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-12-05 11:43:41 -0500 |
commit | 8670c52abcdb260f5366d6fa205a7c7f9b5b1067 (patch) | |
tree | 3781a05c976360f88b736c71316dadc789e02062 /src/cmd/8g/reg.c | |
parent | 3ebebda3a7495402239db4369d59d73749c1bfa2 (diff) | |
parent | 6d3ba1914e289ed223f7bb69f34604c0e2ae5384 (diff) | |
download | go-8670c52abcdb260f5366d6fa205a7c7f9b5b1067.tar.gz |
all: merge dev.cc (81884b89bd88) into default
With this change, default now contains Go 1.5 work.
Any future bug fixes for Go 1.4 in the compilers or
the runtime will have to be made directly to the
release branch.
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..d7394a16d 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 %lld\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"); + } } } |