aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/reader.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-07-26 21:52:42 -0700
committerMatthew Dempsky <mdempsky@google.com>2022-07-28 07:31:47 +0000
commitf9959460940140b280be1f5591ae38b9ab74182e (patch)
tree24dc74e64bc237275446759246b829a819307f01 /src/cmd/compile/internal/noder/reader.go
parentf2851c67fd103b8dd7e84e3d35b896ea49ea4af5 (diff)
downloadgo-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.go35
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.