cmd/compile: factor out code to remove phi argument

CL 358117 fixed a bug that Phi's argument wasn't updated correctly after
removing a predecessor of Block. This CL factor out the code that
updates phi argument into a Block's method, so it's easier to use,
maintain and hopefully prevent that kind of bug in the future.

Change-Id: Ie9741e19ea28f56860425089b6093a381aa10f5b
Reviewed-on: https://go-review.googlesource.com/c/go/+/357964
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Cuong Manh Le 2021-10-24 13:46:54 +07:00
parent f686f6a963
commit 7b554575e4
5 changed files with 32 additions and 22 deletions

View file

@ -279,7 +279,8 @@ func (b *Block) AddEdgeTo(c *Block) {
// removePred removes the ith input edge from b.
// It is the responsibility of the caller to remove
// the corresponding successor edge.
// the corresponding successor edge, and adjust any
// phi values by calling b.removePhiArg(v, i).
func (b *Block) removePred(i int) {
n := len(b.Preds) - 1
if i != n {
@ -322,6 +323,28 @@ func (b *Block) swapSuccessors() {
b.Likely *= -1
}
// removePhiArg removes the ith arg from phi.
// It must be called after calling b.removePred(i) to
// adjust the corresponding phi value of the block:
//
// b.removePred(i)
// for _, v := range b.Values {
// if v.Op != OpPhi {
// continue
// }
// b.removeArg(v, i)
// }
func (b *Block) removePhiArg(phi *Value, i int) {
n := len(b.Preds)
if numPhiArgs := len(phi.Args); numPhiArgs-1 != n {
b.Fatalf("inconsistent state, num predecessors: %d, num phi args: %d", n, numPhiArgs)
}
phi.Args[i].Uses--
phi.Args[i] = phi.Args[n]
phi.Args[n] = nil
phi.Args = phi.Args[:n]
}
// LackingPos indicates whether b is a block whose position should be inherited
// from its successors. This is true if all the values within it have unreliable positions
// and if it is "plain", meaning that there is no control flow that is also very likely

View file

@ -91,14 +91,13 @@ func critical(f *Func) {
b.removePred(i)
// Update corresponding phi args
n := len(b.Preds)
phi.Args[i].Uses--
phi.Args[i] = phi.Args[n]
phi.Args[n] = nil
phi.Args = phi.Args[:n]
b.removePhiArg(phi, i)
// splitting occasionally leads to a phi having
// a single argument (occurs with -N)
if n == 1 {
// TODO(cuonglm,khr): replace this with phielimValue, and
// make removePhiArg incorporates that.
if len(b.Preds) == 1 {
phi.Op = OpCopy
}
// Don't increment i in this case because we moved

View file

@ -348,15 +348,11 @@ func (b *Block) removeEdge(i int) {
c.removePred(j)
// Remove phi args from c's phis.
n := len(c.Preds)
for _, v := range c.Values {
if v.Op != OpPhi {
continue
}
v.Args[j].Uses--
v.Args[j] = v.Args[n]
v.Args[n] = nil
v.Args = v.Args[:n]
c.removePhiArg(v, j)
phielimValue(v)
// Note: this is trickier than it looks. Replacing
// a Phi with a Copy can in general cause problems because

View file

@ -78,11 +78,7 @@ func fuseBranchRedirect(f *Func) bool {
if v.Op != OpPhi {
continue
}
n := len(v.Args)
v.Args[k].Uses--
v.Args[k] = v.Args[n-1]
v.Args[n-1] = nil
v.Args = v.Args[:n-1]
b.removePhiArg(v, k)
phielimValue(v)
}
// Fix up child to have one more predecessor.

View file

@ -196,11 +196,7 @@ func shortcircuitBlock(b *Block) bool {
// Remove b's incoming edge from p.
b.removePred(cidx)
n := len(b.Preds)
ctl.Args[cidx].Uses--
ctl.Args[cidx] = ctl.Args[n]
ctl.Args[n] = nil
ctl.Args = ctl.Args[:n]
b.removePhiArg(ctl, cidx)
// Redirect p's outgoing edge to t.
p.Succs[pi] = Edge{t, len(t.Preds)}