aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2021-05-25 10:13:07 -0400
committerThan McIntosh <thanm@google.com>2021-05-27 18:47:37 +0000
commit56af34f875f55485b4ebc521fe0c695dafb9bc23 (patch)
tree1f3aefba7ff8453200a9243ad34617a48a96ec11 /src/cmd/compile/internal/ssa
parentdb66e9e15d16cfdb555140b26a5f009fd0d23d0e (diff)
downloadgo-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.go16
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)