1
0
mirror of https://github.com/golang/go synced 2024-11-11 22:50:22 -07:00

cmd/5g: fix register opt bug

The width was not being set on the address, which meant
that the optimizer could not find variables that overlapped
with it and mark them as having had their address taken.
This let to the compiler believing variables had been set
but never used and then optimizing away the set.

Fixes #4129.

R=ken2
CC=golang-dev
https://golang.org/cl/6552059
This commit is contained in:
Russ Cox 2012-09-22 10:01:35 -04:00
parent 46f379cc2c
commit 658482d70f
4 changed files with 54 additions and 8 deletions

View File

@ -1199,6 +1199,11 @@ naddr(Node *n, Addr *a, int canemitcode)
if(n == N)
return;
if(n->type != T && n->type->etype != TIDEAL) {
dowidth(n->type);
a->width = n->type->width;
}
switch(n->op) {
default:
fatal("naddr: bad %O %D", n->op, a);
@ -1378,6 +1383,9 @@ naddr(Node *n, Addr *a, int canemitcode)
fatal("naddr: OADDR %d\n", a->type);
}
}
if(a->width < 0)
fatal("naddr: bad width for %N -> %D", n, a);
}
/*

View File

@ -416,10 +416,14 @@ regopt(Prog *firstp)
addrs.b[z] |= bit.b[z];
}
// print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n",
// i, v->addr, v->etype, v->width, v->sym, v->offset);
if(debug['R'] && debug['v'])
print("bit=%2d addr=%d et=%-6E w=%-2d s=%N + %lld\n",
i, v->addr, v->etype, v->width, v->node, v->offset);
}
if(debug['R'] && debug['v'])
dumpit("pass1", firstr);
/*
* pass 2
* turn branch references to pointers
@ -448,6 +452,9 @@ regopt(Prog *firstp)
print(" addr = %Q\n", addrs);
}
if(debug['R'] && debug['v'])
dumpit("pass2", firstr);
/*
* pass 2.5
* find looping structure
@ -457,6 +464,9 @@ regopt(Prog *firstp)
change = 0;
loopit(firstr, nr);
if(debug['R'] && debug['v'])
dumpit("pass2.5", firstr);
/*
* pass 3
* iterate propagating usage
@ -484,6 +494,9 @@ loop11:
if(change)
goto loop1;
if(debug['R'] && debug['v'])
dumpit("pass3", firstr);
/*
* pass 4
@ -500,6 +513,9 @@ loop2:
addsplits();
if(debug['R'] && debug['v'])
dumpit("pass4", firstr);
if(debug['R'] > 1) {
print("\nprop structure:\n");
for(r = firstr; r != R; r = r->link) {
@ -551,6 +567,9 @@ loop2:
r->act.b[0] &= ~REGBITS;
}
if(debug['R'] && debug['v'])
dumpit("pass4.5", firstr);
/*
* pass 5
* isolate regions
@ -613,6 +632,9 @@ loop2:
brk:
qsort(region, nregion, sizeof(region[0]), rcmp);
if(debug['R'] && debug['v'])
dumpit("pass5", firstr);
/*
* pass 6
* determine used registers (paint2)
@ -641,6 +663,10 @@ brk:
paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
rgp++;
}
if(debug['R'] && debug['v'])
dumpit("pass6", firstr);
/*
* pass 7
* peep-hole on basic block
@ -649,6 +675,9 @@ brk:
peep();
}
if(debug['R'] && debug['v'])
dumpit("pass7", firstr);
/*
* last pass
* eliminate nops
@ -935,6 +964,8 @@ mkvar(Reg *r, Adr *a)
et = a->etype;
o = a->offset;
w = a->width;
if(w < 0)
fatal("bad width %d for %D", w, a);
for(i=0; i<nvar; i++) {
v = var+i;
@ -1705,7 +1736,7 @@ fixjmp(Prog *firstp)
}
if(debug['R'] && debug['v'])
print("\n");
// pass 2: mark all reachable code alive
mark(firstp);

View File

@ -579,8 +579,9 @@ regopt(Prog *firstp)
addrs.b[z] |= bit.b[z];
}
// print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n",
// i, v->addr, v->etype, v->width, v->sym, v->offset);
if(debug['R'] && debug['v'])
print("bit=%2d addr=%d et=%-6E w=%-2d s=%N + %lld\n",
i, v->addr, v->etype, v->width, v->node, v->offset);
}
if(debug['R'] && debug['v'])
@ -996,6 +997,8 @@ mkvar(Reg *r, Adr *a)
et = a->etype;
o = a->offset;
w = a->width;
if(w < 0)
fatal("bad width %d for %D", w, a);
flag = 0;
for(i=0; i<nvar; i++) {
@ -1038,7 +1041,8 @@ mkvar(Reg *r, Adr *a)
v->node = node;
if(debug['R'])
print("bit=%2d et=%2E w=%d %#N %D\n", i, et, w, node, a);
print("bit=%2d et=%2d w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr);
ostats.nvar++;
bit = blsh(i);

View File

@ -474,8 +474,9 @@ regopt(Prog *firstp)
addrs.b[z] |= bit.b[z];
}
// print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n",
// i, v->addr, v->etype, v->width, v->sym, v->offset);
if(debug['R'] && debug['v'])
print("bit=%2d addr=%d et=%-6E w=%-2d s=%N + %lld\n",
i, v->addr, v->etype, v->width, v->node, v->offset);
}
if(debug['R'] && debug['v'])
@ -864,6 +865,8 @@ mkvar(Reg *r, Adr *a)
et = a->etype;
o = a->offset;
w = a->width;
if(w < 0)
fatal("bad width %d for %D", w, a);
flag = 0;
for(i=0; i<nvar; i++) {