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:
parent
46f379cc2c
commit
658482d70f
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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++) {
|
||||
|
Loading…
Reference in New Issue
Block a user