// 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 {
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
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
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
// 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)}