]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] Protect control value from being moved away from end of block
authorDaniel Morsing <daniel.morsing@gmail.com>
Sat, 13 Jun 2015 18:27:26 +0000 (19:27 +0100)
committerDaniel Morsing <daniel.morsing@gmail.com>
Sun, 14 Jun 2015 16:40:40 +0000 (16:40 +0000)
If there isn't a value dependency between the control value of a
block and some other value, the schedule pass might move the control
value to a spot that is not EOB. Fix by handling the control value
specially like phis.

Change-Id: Iddaf0924d98c5b3d9515c3ced927b0c85722818c
Reviewed-on: https://go-review.googlesource.com/11071
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/schedule.go

index b93b0d8a45581a6532f53307588ad9ba390ddcbc..60d2cd54608e8b1d83659dd4f67797d6e4f918f0 100644 (file)
@@ -57,6 +57,9 @@ func schedule(f *Func) {
                // Topologically sort the values in b.
                order = order[:0]
                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)"
@@ -79,13 +82,13 @@ func schedule(f *Func) {
                                        // Note that v is not popped.  We leave it in place
                                        // until all its children have been explored.
                                        for _, w := range v.Args {
-                                               if w.Block == b && w.Op != OpPhi && state[w.ID] == unmarked {
+                                               if w.Block == b && w.Op != OpPhi && w != b.Control && state[w.ID] == unmarked {
                                                        state[w.ID] = found
                                                        queue = append(queue, w)
                                                }
                                        }
                                        for _, w := range additionalEdges[v.ID] {
-                                               if w.Block == b && w.Op != OpPhi && state[w.ID] == unmarked {
+                                               if w.Block == b && w.Op != OpPhi && w != b.Control && state[w.ID] == unmarked {
                                                        state[w.ID] = found
                                                        queue = append(queue, w)
                                                }
@@ -99,6 +102,9 @@ func schedule(f *Func) {
                                }
                        }
                }
+               if b.Control != nil {
+                       order = append(order, b.Control)
+               }
                copy(b.Values, order)
        }
        // TODO: only allow one live flags type (x86)