diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2022-07-26 21:52:42 -0700 |
|---|---|---|
| committer | Matthew Dempsky <mdempsky@google.com> | 2022-07-28 07:31:47 +0000 |
| commit | f9959460940140b280be1f5591ae38b9ab74182e (patch) | |
| tree | 24dc74e64bc237275446759246b829a819307f01 /src/cmd/compile/internal/noder/reader.go | |
| parent | f2851c67fd103b8dd7e84e3d35b896ea49ea4af5 (diff) | |
| download | go-f9959460940140b280be1f5591ae38b9ab74182e.tar.xz | |
[dev.unified] cmd/compile: implement simple inline body pruning heuristic
An important optimization in the existing export data format is the
pruning of unreachable inline bodies. That is, when re-exporting
transitively imported types, omitting the inline bodies for methods
that can't actually be needed due to importing that package.
The existing logic (implemented in typecheck/crawler.go) is fairly
sophisticated, but also relies on actually expanding inline bodies in
the process, which is undesirable. However, including all inline
bodies is also prohibitive for testing GOEXPERIMENT=unified against
very large Go code bases that impose size limits on build action
inputs.
As a short-term solution, this CL implements a simple heuristic for
GOEXPERIMENT=unified: include the inline bodies for all
locally-declared functions/methods, and for any imported
functions/methods that were inlined into this package.
Change-Id: I686964a0cd9262b77d3d5587f89cfbcfe8b2e521
Reviewed-on: https://go-review.googlesource.com/c/go/+/419675
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/reader.go')
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index 0a382e1c9b..9458332fc8 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -897,6 +897,8 @@ func (r *reader) funcExt(name *ir.Name) { typecheck.Func(fn) if r.Bool() { + assert(name.Defn == nil) + fn.ABI = obj.ABI(r.Uint64()) // Escape analysis. @@ -911,7 +913,6 @@ func (r *reader) funcExt(name *ir.Name) { Cost: int32(r.Len()), CanDelayResults: r.Bool(), } - r.addBody(name.Func) } } else { r.addBody(name.Func) @@ -967,10 +968,26 @@ func (r *reader) pragmaFlag() ir.PragmaFlag { // @@@ Function bodies -// bodyReader tracks where the serialized IR for a function's body can -// be found. +// bodyReader tracks where the serialized IR for a local or imported, +// generic function's body can be found. var bodyReader = map[*ir.Func]pkgReaderIndex{} +// importBodyReader tracks where the serialized IR for an imported, +// static (i.e., non-generic) function body can be read. +var importBodyReader = map[*types.Sym]pkgReaderIndex{} + +// bodyReaderFor returns the pkgReaderIndex for reading fn's +// serialized IR, and whether one was found. +func bodyReaderFor(fn *ir.Func) (pri pkgReaderIndex, ok bool) { + if fn.Nname.Defn != nil { + pri, ok = bodyReader[fn] + assert(ok) // must always be available + } else { + pri, ok = importBodyReader[fn.Sym()] + } + return +} + // todoBodies holds the list of function bodies that still need to be // constructed. var todoBodies []*ir.Func @@ -978,15 +995,13 @@ var todoBodies []*ir.Func // addBody reads a function body reference from the element bitstream, // and associates it with fn. func (r *reader) addBody(fn *ir.Func) { + // addBody should only be called for local functions or imported + // generic functions; see comment in funcExt. + assert(fn.Nname.Defn != nil) + pri := pkgReaderIndex{r.p, r.Reloc(pkgbits.RelocBody), r.dict} bodyReader[fn] = pri - if fn.Nname.Defn == nil { - // Don't read in function body for imported functions. - // See comment in funcExt. - return - } - if r.curfn == nil { todoBodies = append(todoBodies, fn) return @@ -2225,7 +2240,7 @@ func InlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExp // TODO(mdempsky): Turn callerfn into an explicit parameter. callerfn := ir.CurFunc - pri, ok := bodyReader[fn] + pri, ok := bodyReaderFor(fn) if !ok { // TODO(mdempsky): Reconsider this diagnostic's wording, if it's // to be included in Go 1.20. |
