]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile/internal/ssa: ensure Phi ops are scheduled first
authorKeith Randall <khr@golang.org>
Tue, 14 Jul 2015 06:52:59 +0000 (23:52 -0700)
committerKeith Randall <khr@golang.org>
Tue, 14 Jul 2015 15:39:56 +0000 (15:39 +0000)
Phi ops should always be scheduled first.  They have the semantics
of all happening simultaneously at the start of the block.  The regalloc
phase assumes all the phis will appear first.

Change-Id: I30291e1fa384a0819205218f1d1ec3aef6d538dd
Reviewed-on: https://go-review.googlesource.com/12154
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/cmd/compile/internal/ssa/schedule.go

index 60d2cd54608e8b1d83659dd4f67797d6e4f918f0..15e8ace391b5335dab7c5dc5243b6b9a61d5eca3 100644 (file)
@@ -54,16 +54,28 @@ func schedule(f *Func) {
                        }
                }
 
-               // Topologically sort the values in b.
                order = order[:0]
+
+               // Schedule phis first
                for _, v := range b.Values {
-                       if v == b.Control {
-                               continue
-                       }
                        if v.Op == OpPhi {
-                               // Phis all go first.  We handle phis specially
-                               // because they may have self edges "a = phi(a, b, c)"
+                               // TODO: what if a phi is also a control op?  It happens for
+                               // mem ops all the time, which shouldn't matter.  But for
+                               // regular ops we might be violating invariants about where
+                               // control ops live.
+                               if v == b.Control && !v.Type.IsMemory() {
+                                       f.Unimplementedf("phi is a control op %s %s", v, b)
+                               }
                                order = append(order, v)
+                       }
+               }
+
+               // Topologically sort the non-phi values in b.
+               for _, v := range b.Values {
+                       if v.Op == OpPhi {
+                               continue
+                       }
+                       if v == b.Control {
                                continue
                        }
                        if state[v.ID] != unmarked {