diff options
author | Than McIntosh <thanm@google.com> | 2021-05-25 10:13:07 -0400 |
---|---|---|
committer | Than McIntosh <thanm@google.com> | 2021-05-27 18:47:37 +0000 |
commit | 56af34f875f55485b4ebc521fe0c695dafb9bc23 (patch) | |
tree | 1f3aefba7ff8453200a9243ad34617a48a96ec11 /src/cmd/compile/internal/ssa | |
parent | db66e9e15d16cfdb555140b26a5f009fd0d23d0e (diff) | |
download | go-56af34f875f55485b4ebc521fe0c695dafb9bc23.tar.gz go-56af34f875f55485b4ebc521fe0c695dafb9bc23.zip |
cmd/compile: place reg spills after OpArg{Int,Float}Reg ops
Tweak the register allocator to maintain the invariant that
OpArg{Int,Float}Reg values are placed together at the start of the
entry block, before any other non-pseudo-op values. Without this
change, when the register allocator adds spills we can wind up with an
interleaving of OpArg*Reg and stores, which complicates debug location
analysis.
Updates #40724.
Change-Id: Icf30dd814a9e25263ecbea2e48feb840a6e7f2bd
Reviewed-on: https://go-review.googlesource.com/c/go/+/322630
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa')
-rw-r--r-- | src/cmd/compile/internal/ssa/regalloc.go | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index c81d5574fe..3b90b8769c 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -1882,6 +1882,10 @@ func (s *regAllocState) placeSpills() { phiRegs[b.ID] = m } + mustBeFirst := func(op Op) bool { + return op.isLoweredGetClosurePtr() || op == OpPhi || op == OpArgIntReg || op == OpArgFloatReg + } + // Start maps block IDs to the list of spills // that go at the start of the block (but after any phis). start := map[ID][]*Value{} @@ -1971,7 +1975,7 @@ func (s *regAllocState) placeSpills() { // Put the spill in the best block we found. spill.Block = best spill.AddArg(bestArg) - if best == v.Block && v.Op != OpPhi { + if best == v.Block && !mustBeFirst(v.Op) { // Place immediately after v. after[v.ID] = append(after[v.ID], spill) } else { @@ -1983,15 +1987,15 @@ func (s *regAllocState) placeSpills() { // Insert spill instructions into the block schedules. var oldSched []*Value for _, b := range s.visitOrder { - nphi := 0 + nfirst := 0 for _, v := range b.Values { - if v.Op != OpPhi { + if !mustBeFirst(v.Op) { break } - nphi++ + nfirst++ } - oldSched = append(oldSched[:0], b.Values[nphi:]...) - b.Values = b.Values[:nphi] + oldSched = append(oldSched[:0], b.Values[nfirst:]...) + b.Values = b.Values[:nfirst] b.Values = append(b.Values, start[b.ID]...) for _, v := range oldSched { b.Values = append(b.Values, v) |