summaryrefslogtreecommitdiff
path: root/src/cmd/8g/reg.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-12-05 11:43:41 -0500
committerRuss Cox <rsc@golang.org>2014-12-05 11:43:41 -0500
commit8670c52abcdb260f5366d6fa205a7c7f9b5b1067 (patch)
tree3781a05c976360f88b736c71316dadc789e02062 /src/cmd/8g/reg.c
parent3ebebda3a7495402239db4369d59d73749c1bfa2 (diff)
parent6d3ba1914e289ed223f7bb69f34604c0e2ae5384 (diff)
downloadgo-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.c141
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");
+ }
}
}