]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: check that phis are always first after scheduling
authorKeith Randall <khr@golang.org>
Tue, 6 Jun 2017 22:25:29 +0000 (15:25 -0700)
committerKeith Randall <khr@golang.org>
Wed, 7 Jun 2017 00:13:20 +0000 (00:13 +0000)
Update #20178

Change-Id: I603f77268ed38afdd84228c775efe006f08f14a7
Reviewed-on: https://go-review.googlesource.com/45018
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/cmd/compile/internal/ssa/check.go
src/cmd/compile/internal/ssa/deadstore.go
src/cmd/compile/internal/ssa/rewrite.go

index 82aa9f1ce89fca1df0cb878982798f048d2cb036..17f683fb10c984dbe2e6a227166b44a1f3b90730 100644 (file)
@@ -444,6 +444,22 @@ func memCheck(f *Func) {
                        }
                }
        }
+
+       // Check that after scheduling, phis are always first in the block.
+       if f.scheduled {
+               for _, b := range f.Blocks {
+                       seenNonPhi := false
+                       for _, v := range b.Values {
+                               if v.Op == OpPhi {
+                                       if seenNonPhi {
+                                               f.Fatalf("phi after non-phi @ %s: %s", b, v)
+                                       }
+                               } else {
+                                       seenNonPhi = true
+                               }
+                       }
+               }
+       }
 }
 
 // domCheck reports whether x dominates y (including x==y).
index bac4930e7814d38bcd9bfc26ac7e7cdee5eef80a..08a2c6df14aa6061ca6d9e027fcc03259398127e 100644 (file)
@@ -117,7 +117,11 @@ func dse(f *Func) {
                }
                // walk to previous store
                if v.Op == OpPhi {
-                       continue // At start of block.  Move on to next block.
+                       // At start of block.  Move on to next block.
+                       // The memory phi, if it exists, is always
+                       // the first logical store in the block.
+                       // (Even if it isn't the first in the current b.Values order.)
+                       continue
                }
                for _, a := range v.Args {
                        if a.Block == b && a.Type.IsMemory() {
index 06595586c180488daa916833784233553bb48299..b42d53032c3e8ff8e2b7abd7dcb7cf8a47cd5697 100644 (file)
@@ -211,6 +211,8 @@ search:
                }
                if v.Op == OpPhi {
                        // A Phi implies we have reached the top of the block.
+                       // The memory phi, if it exists, is always
+                       // the first logical store in the block.
                        continue search
                }
                if v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() {
@@ -228,6 +230,8 @@ search:
                                const limit = 50
                                for i := 0; i < limit; i++ {
                                        if m.Op == OpPhi {
+                                               // The memory phi, if it exists, is always
+                                               // the first logical store in the block.
                                                break
                                        }
                                        if m.Block.ID != target.Block.ID {