]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: perform minimal phi elimination during critical
authorTodd Neal <todd@tneal.org>
Fri, 18 Mar 2016 12:05:58 +0000 (07:05 -0500)
committerTodd Neal <todd@tneal.org>
Fri, 18 Mar 2016 15:35:49 +0000 (15:35 +0000)
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>
src/cmd/compile/internal/ssa/critical.go

index 38d4ca40dd197f97c2ff633c0c16532c5b05e571..cd6c58b0b1456c9f65789f947289e0776208d5c9 100644 (file)
@@ -53,6 +53,9 @@ func critical(f *Func) {
                                // find or record the block that we used to split
                                // critical edges for this argument
                                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.Line = c.Line
                                        blocks[argID] = d
@@ -101,6 +104,11 @@ func critical(f *Func) {
                if phi != nil {
                        phi.Args = filterNilValues(phi.Args)
                        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
+                       }
                }
        }
 }