]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: don't sink spills that satisfy merge edges in SSA
authorCherry Zhang <cherryyz@google.com>
Mon, 11 Jul 2016 05:34:46 +0000 (23:34 -0600)
committerCherry Zhang <cherryyz@google.com>
Fri, 15 Jul 2016 18:20:17 +0000 (18:20 +0000)
If a spill is used to satisfy a merge edge (in shuffle), don't sink
it out of loop.

This is found in the following code (on ARM) where there is a stack
Phi (v268) inside a loop (b36 -> ... -> b47 -> b38 -> b36).

(before shuffle)
  b36: <- b34 b38
    ...
    v268 = Phi <int> v410 v360 : autotmp_198[int]
    ...
    ... -> b47
  b47: <- b44
    ...
    v360 = ... : R6
    v230 = StoreReg <int> v360 : autotmp_198[int]
    v261 = CMPconst <flags> [0] v360
    EQ v261 -> b49 b38 (unlikely)
  b38: <- b47
    ...
    Plain -> b36

During shuffle, v230 (as spill of v360) is found to satisfy v268, but
it didn't record its use in shuffle, and v230 is sunk out of the loop
(to b49), which leads to bad value in v268.

This seems never happened on AMD64 (in make.bash), until 4 registers
are removed.

Change-Id: I01dfc28ae461e853b36977c58bcfc0669e556660
Reviewed-on: https://go-review.googlesource.com/24858
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/regalloc.go

index 9f0d13b29ac551cdcc23a0f060cde8a21e4b00bc..eba90fd051522bd904d77e9a9c49aac592f8f2be 100644 (file)
@@ -1818,6 +1818,9 @@ func (e *edgeState) processDest(loc Location, vid ID, splice **Value) bool {
                        (*splice).Uses--
                        *splice = occupant.c
                        occupant.c.Uses++
+                       if occupant.c.Op == OpStoreReg {
+                               e.s.lateSpillUse(vid)
+                       }
                }
                // Note: if splice==nil then c will appear dead. This is
                // non-SSA formed code, so be careful after this pass not to run