mirror of
https://github.com/golang/go
synced 2024-10-02 22:25:08 +00:00
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:
parent
f686f6a963
commit
7b554575e4
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)}
|
||||
|
|
Loading…
Reference in a new issue