1
0
mirror of https://github.com/golang/go synced 2024-11-24 05:30:24 -07:00

cmd/compile: perform minimal phi elimination during critical

Phi splitting sometimes leads to a phi with only a single predecessor.
This must be replaced with a copy to maintain a valid SSA form.

Fixes #14857

Change-Id: I5ab2423fb6c85a061928e3206b02185ea8c79cd7
Reviewed-on: https://go-review.googlesource.com/20826
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Todd Neal 2016-03-18 07:05:58 -05:00
parent 2330ae8cf8
commit b2dc1f82a5

View File

@ -53,6 +53,9 @@ func critical(f *Func) {
// find or record the block that we used to split // find or record the block that we used to split
// critical edges for this argument // critical edges for this argument
if d = blocks[argID]; d == nil { if d = blocks[argID]; d == nil {
// splitting doesn't necessarily remove the critical edge,
// since we're iterating over len(f.Blocks) above, this forces
// the new blocks to be re-examined.
d = f.NewBlock(BlockPlain) d = f.NewBlock(BlockPlain)
d.Line = c.Line d.Line = c.Line
blocks[argID] = d blocks[argID] = d
@ -101,6 +104,11 @@ func critical(f *Func) {
if phi != nil { if phi != nil {
phi.Args = filterNilValues(phi.Args) phi.Args = filterNilValues(phi.Args)
b.Preds = filterNilBlocks(b.Preds) b.Preds = filterNilBlocks(b.Preds)
// splitting occasionally leads to a phi having
// a single argument (occurs with -N)
if len(phi.Args) == 1 {
phi.Op = OpCopy
}
} }
} }
} }