cmd/compile: add cache of sizeable objects so they can be reused

We kind of have this mechanism already, just normalizing it and
using it in a bunch of places. Previously a bunch of places cached
slices only for the duration of a single function compilation. Now
we can reuse slices across a whole compiler run.

Use a sync.Pool of powers-of-two sizes. This lets us use not
too much memory, and avoid holding onto memory we're no longer
using when a GC happens.

There's a few different types we need, so generate the code for it.
Generics would be useful here, but we can't use generics in the
compiler because of bootstrapping.

Change-Id: I6cf37e7b7b2e802882aaa723a0b29770511ccd82
Reviewed-on: https://go-review.googlesource.com/c/go/+/444820
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Keith Randall 2022-10-18 16:07:36 -07:00 committed by Keith Randall
parent 7ddc45263c
commit 68bd383368
21 changed files with 656 additions and 213 deletions

View file

@ -146,6 +146,7 @@ func regalloc(f *Func) {
var s regAllocState
s.init(f)
s.regalloc(f)
s.close()
}
type register uint8
@ -357,6 +358,12 @@ func (s *regAllocState) clobberRegs(m regMask) {
// setOrig records that c's original value is the same as
// v's original value.
func (s *regAllocState) setOrig(c *Value, v *Value) {
if int(c.ID) >= cap(s.orig) {
x := s.f.Cache.allocValueSlice(int(c.ID) + 1)
copy(x, s.orig)
s.f.Cache.freeValueSlice(s.orig)
s.orig = x
}
for int(c.ID) >= len(s.orig) {
s.orig = append(s.orig, nil)
}
@ -664,7 +671,7 @@ func (s *regAllocState) init(f *Func) {
s.f.Cache.regallocValues = make([]valState, nv)
}
s.values = s.f.Cache.regallocValues
s.orig = make([]*Value, nv)
s.orig = s.f.Cache.allocValueSlice(nv)
s.copies = make(map[*Value]bool)
for _, b := range s.visitOrder {
for _, v := range b.Values {
@ -728,6 +735,10 @@ func (s *regAllocState) init(f *Func) {
}
}
func (s *regAllocState) close() {
s.f.Cache.freeValueSlice(s.orig)
}
// Adds a use record for id at distance dist from the start of the block.
// All calls to addUse must happen with nonincreasing dist.
func (s *regAllocState) addUse(id ID, dist int32, pos src.XPos) {