mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
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>
This commit is contained in:
parent
db66e9e15d
commit
56af34f875
|
@ -1882,6 +1882,10 @@ func (s *regAllocState) placeSpills() {
|
||||||
phiRegs[b.ID] = m
|
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
|
// Start maps block IDs to the list of spills
|
||||||
// that go at the start of the block (but after any phis).
|
// that go at the start of the block (but after any phis).
|
||||||
start := map[ID][]*Value{}
|
start := map[ID][]*Value{}
|
||||||
|
@ -1971,7 +1975,7 @@ func (s *regAllocState) placeSpills() {
|
||||||
// Put the spill in the best block we found.
|
// Put the spill in the best block we found.
|
||||||
spill.Block = best
|
spill.Block = best
|
||||||
spill.AddArg(bestArg)
|
spill.AddArg(bestArg)
|
||||||
if best == v.Block && v.Op != OpPhi {
|
if best == v.Block && !mustBeFirst(v.Op) {
|
||||||
// Place immediately after v.
|
// Place immediately after v.
|
||||||
after[v.ID] = append(after[v.ID], spill)
|
after[v.ID] = append(after[v.ID], spill)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1983,15 +1987,15 @@ func (s *regAllocState) placeSpills() {
|
||||||
// Insert spill instructions into the block schedules.
|
// Insert spill instructions into the block schedules.
|
||||||
var oldSched []*Value
|
var oldSched []*Value
|
||||||
for _, b := range s.visitOrder {
|
for _, b := range s.visitOrder {
|
||||||
nphi := 0
|
nfirst := 0
|
||||||
for _, v := range b.Values {
|
for _, v := range b.Values {
|
||||||
if v.Op != OpPhi {
|
if !mustBeFirst(v.Op) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
nphi++
|
nfirst++
|
||||||
}
|
}
|
||||||
oldSched = append(oldSched[:0], b.Values[nphi:]...)
|
oldSched = append(oldSched[:0], b.Values[nfirst:]...)
|
||||||
b.Values = b.Values[:nphi]
|
b.Values = b.Values[:nfirst]
|
||||||
b.Values = append(b.Values, start[b.ID]...)
|
b.Values = append(b.Values, start[b.ID]...)
|
||||||
for _, v := range oldSched {
|
for _, v := range oldSched {
|
||||||
b.Values = append(b.Values, v)
|
b.Values = append(b.Values, v)
|
||||||
|
|
Loading…
Reference in a new issue