From: Keith Randall Date: Wed, 22 Mar 2017 00:12:33 +0000 (-0700) Subject: cmd/compile: initialize loop depths X-Git-Tag: go1.9beta1~1019 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=27bc723b5130d11e4d3bae9566a3043a2dff2b8a;p=gostls13.git cmd/compile: initialize loop depths 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 --- diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index a1b07433ae..4e0c49f6ed 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -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 diff --git a/src/cmd/compile/internal/ssa/regalloc_test.go b/src/cmd/compile/internal/ssa/regalloc_test.go index e52c6c1b27..19edaedb6a 100644 --- a/src/cmd/compile/internal/ssa/regalloc_test.go +++ b/src/cmd/compile/internal/ssa/regalloc_test.go @@ -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()) + } + } +}