mirror of
https://github.com/golang/go
synced 2024-11-24 08:40:14 -07:00
[dev.ssa] Protect control value from being moved away from end of block
If there isn't a value dependency between the control value of a block and some other value, the schedule pass might move the control value to a spot that is not EOB. Fix by handling the control value specially like phis. Change-Id: Iddaf0924d98c5b3d9515c3ced927b0c85722818c Reviewed-on: https://go-review.googlesource.com/11071 Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
8f22b5292f
commit
2efdaefdb0
@ -57,6 +57,9 @@ func schedule(f *Func) {
|
||||
// Topologically sort the values in b.
|
||||
order = order[:0]
|
||||
for _, v := range b.Values {
|
||||
if v == b.Control {
|
||||
continue
|
||||
}
|
||||
if v.Op == OpPhi {
|
||||
// Phis all go first. We handle phis specially
|
||||
// because they may have self edges "a = phi(a, b, c)"
|
||||
@ -79,13 +82,13 @@ func schedule(f *Func) {
|
||||
// Note that v is not popped. We leave it in place
|
||||
// until all its children have been explored.
|
||||
for _, w := range v.Args {
|
||||
if w.Block == b && w.Op != OpPhi && state[w.ID] == unmarked {
|
||||
if w.Block == b && w.Op != OpPhi && w != b.Control && state[w.ID] == unmarked {
|
||||
state[w.ID] = found
|
||||
queue = append(queue, w)
|
||||
}
|
||||
}
|
||||
for _, w := range additionalEdges[v.ID] {
|
||||
if w.Block == b && w.Op != OpPhi && state[w.ID] == unmarked {
|
||||
if w.Block == b && w.Op != OpPhi && w != b.Control && state[w.ID] == unmarked {
|
||||
state[w.ID] = found
|
||||
queue = append(queue, w)
|
||||
}
|
||||
@ -99,6 +102,9 @@ func schedule(f *Func) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if b.Control != nil {
|
||||
order = append(order, b.Control)
|
||||
}
|
||||
copy(b.Values, order)
|
||||
}
|
||||
// TODO: only allow one live flags type (x86)
|
||||
|
Loading…
Reference in New Issue
Block a user