]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: initialize loop depths
authorKeith Randall <khr@golang.org>
Wed, 22 Mar 2017 00:12:33 +0000 (17:12 -0700)
committerKeith Randall <khr@golang.org>
Thu, 23 Mar 2017 16:41:22 +0000 (16:41 +0000)
Regalloc uses loop depths - make sure they are initialized!

Test to make sure we aren't pushing spills into loops.

This fixes a generated-code performance bug introduced with
the better spill placement change:
https://go-review.googlesource.com/c/34822/

Update #19595

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

index a1b07433ae2535df962015fada9dcd2f79d10289..4e0c49f6eda64342d9e163517b26bf286f56b831 100644 (file)
@@ -2176,6 +2176,7 @@ func (s *regAllocState) computeLive() {
        // out to all of them.
        po := f.postorder()
        s.loopnest = f.loopnest()
+       s.loopnest.calculateDepths()
        for {
                changed := false
 
index e52c6c1b27c5ccd5083a3f9c57db3bf39f28e2e6..19edaedb6ab4b65cb9af3e182c7e054677a6c4fc 100644 (file)
@@ -31,3 +31,38 @@ func TestLiveControlOps(t *testing.T) {
        regalloc(f.f)
        checkFunc(f.f)
 }
+
+// Test to make sure we don't push spills into loops.
+// See issue #19595.
+func TestSpillWithLoop(t *testing.T) {
+       c := testConfig(t)
+       f := c.Fun("entry",
+               Bloc("entry",
+                       Valu("mem", OpInitMem, TypeMem, 0, nil),
+                       Valu("ptr", OpArg, TypeInt64Ptr, 0, c.Frontend().Auto(TypeInt64)),
+                       Valu("cond", OpArg, TypeBool, 0, c.Frontend().Auto(TypeBool)),
+                       Valu("ld", OpAMD64MOVQload, TypeInt64, 0, nil, "ptr", "mem"), // this value needs a spill
+                       Goto("loop"),
+               ),
+               Bloc("loop",
+                       Valu("memphi", OpPhi, TypeMem, 0, nil, "mem", "call"),
+                       Valu("call", OpAMD64CALLstatic, TypeMem, 0, nil, "memphi"),
+                       Valu("test", OpAMD64CMPBconst, TypeFlags, 0, nil, "cond"),
+                       Eq("test", "next", "exit"),
+               ),
+               Bloc("next",
+                       Goto("loop"),
+               ),
+               Bloc("exit",
+                       Valu("store", OpAMD64MOVQstore, TypeMem, 0, nil, "ptr", "ld", "call"),
+                       Exit("store"),
+               ),
+       )
+       regalloc(f.f)
+       checkFunc(f.f)
+       for _, v := range f.blocks["loop"].Values {
+               if v.Op == OpStoreReg {
+                       t.Errorf("spill inside loop %s", v.LongString())
+               }
+       }
+}