summaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/linker.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-08-04 10:32:51 -0700
committerMatthew Dempsky <mdempsky@google.com>2022-08-04 10:32:51 -0700
commita10afb15e060386615dcc0ecf2bd60ca3abbc04c (patch)
treea89e2d4e921b2b966aee9d86cbdd3d5ff9df01c7 /src/cmd/compile/internal/noder/linker.go
parent85d87b9c7507628144db51bd1e7e80cc3afed128 (diff)
parentd558507db42d600e5ad82748bda0cb91df57b97d (diff)
downloadgo-git-a10afb15e060386615dcc0ecf2bd60ca3abbc04c.tar.gz
all: REVERSE MERGE dev.unified (d558507) into master
This commit is a REVERSE MERGE. It merges dev.unified back into its parent branch, master. This marks the end of development on dev.unified. Merge List: + 2022-08-04 d558507db4 [dev.unified] all: merge master (85d87b9) into dev.unified + 2022-08-03 c9f2150cfb [dev.unified] cmd/compile: start using runtime dictionaries + 2022-07-30 994ff78ba0 [dev.unified] go/internal: set underlying types in proper order + 2022-07-28 23554d4744 [dev.unified] all: merge master (462b78f) into dev.unified + 2022-07-28 c8d5ccf82e [dev.unified] go/internal/gcimporter: flatten imports + 2022-07-28 ac0844ec27 [dev.unified] cmd/compile: move "has init" to private metadata + 2022-07-28 f995946094 [dev.unified] cmd/compile: implement simple inline body pruning heuristic + 2022-07-28 f2851c67fd [dev.unified] cmd/compile: allow inlining to fail gracefully + 2022-07-28 831fdf1dff [dev.unified] cmd/compile: extract nil handling from exprType + 2022-07-28 92798176e7 [dev.unified] cmd/compile: write iface conversion RTTI into unified IR + 2022-07-28 9b70178d58 [dev.unified] cmd/compile: write RTTI into unified IR export data + 2022-07-25 fc72b7705d [dev.unified] cmd/compile: add method expressions to dictionaries + 2022-07-25 f48fa643f1 [dev.unified] cmd/compile: remove obsolete RTTI wiring + 2022-07-22 131f981df0 [dev.unified] cmd/compile: make Unified IR always writes concrete type for const exprs + 2022-07-20 ae43bdc3e3 Merge "[dev.unified] all: merge master (8e1e64c) into dev.unified" into dev.unified + 2022-07-19 7a8ba83b72 [dev.unified] cmd/compile/internal/reflectdata: remove hasRType's `required` param + 2022-07-19 64cd6faa13 [dev.unified] cmd/compile/internal/noder: simplify mixed tag/case RTTI wiring + 2022-07-19 a4c5198a3c [dev.unified] cmd/compile/internal/noder: better switch statements + 2022-07-19 318027044a [dev.unified] cmd/compile/internal/noder: explicit nil handling + 2022-07-19 e971b6a9be [dev.unified] test: add switch test case for tricky nil handling + 2022-07-19 878439cfe5 [dev.unified] cmd/compile/internal/noder: preserve RTTI for select statements + 2022-07-19 e376746e54 [dev.unified] cmd/compile/internal/noder: wire RTTI for implicit conversions + 2022-07-19 c846fd8e13 [dev.unified] cmd/compile/internal/noder: implicit conversions for binary exprs + 2022-07-19 ebd34e3e45 [dev.unified] test: relax panic message expectations + 2022-07-19 76a82f09d6 [dev.unified] cmd/compile/internal/noder: prefer *At functions + 2022-07-19 de649a2a98 [dev.unified] all: merge master (8e1e64c) into dev.unified + 2022-07-19 055a5e55fa [dev.unified] test: change Unicode file/package name to use characters not translated by macOS. + 2022-07-18 2cf632cd57 [dev.unified] cmd/compile/internal/reflectdata: prefer ITabAddrAt in ConvIfaceTypeWord + 2022-07-12 9371a65584 internal/pkgbits: change EnableSync into a dynamic knob + 2022-07-01 d667be8831 [dev.unified] cmd/compile/internal/walk: RType fields for range assignments + 2022-06-30 1b838e9556 [dev.unified] all: merge master (993c387) into dev.unified + 2022-06-30 0a503cf43a [dev.unified] cmd/compile: refactor `range` desugaring + 2022-06-30 3635b07d16 [dev.unified] cmd/compile/internal/noder: implicit conversions for multi-valued expressions + 2022-06-30 e7219cc093 [dev.unified] cmd/compile/internal/noder: refactor N:1 expression handling + 2022-06-30 2f3ef73e18 [dev.unified] test: tweak nilcheck test + 2022-06-30 95d7ce9ab1 [dev.unified] test: break escape_iface.go into unified/nounified variants + 2022-06-30 f751319a0b [dev.unified] test: relax live_regabi.go + 2022-06-30 e3cdc981c8 [dev.unified] cmd/compile/internal/walk: fix typo in debug print + 2022-06-29 2280d897d6 [dev.unified] test: add regress test for generic select statements + 2022-06-27 4b78ece3d7 [dev.unified] cmd/compile: drop package height from Unified IR importer + 2022-06-27 398d46d538 [dev.unified] cmd/compile/internal/types2: remove package height + 2022-06-24 e7100adbca [dev.unified] all: merge master (5a1c5b8) into dev.unified + 2022-06-23 09a838ad86 [dev.unified] cmd/compile: rename haveRType and implicitExpr + 2022-06-23 421e9e9db2 [dev.unified] cmd/compile: implicit conversions for return statements + 2022-06-23 a3fea7796a [dev.unified] cmd/compile/internal/noder: implicit conversions for writer.assignStmt + 2022-06-23 82a958a661 [dev.unified] cmd/compile/internal/noder: refactor stmtAssign generation + 2022-06-23 711dacd8cf [dev.unified] cmd/compile/internal/noder: implicit conversion of call arguments + 2022-06-23 46b01ec667 [dev.unified] cmd/compile/internal/noder: remove needType logic + 2022-06-23 a3e474f867 [dev.unified] cmd/compile/internal/noder: implicit conversions for complits + 2022-06-23 5f5422a2dd [dev.unified] cmd/compile/internal/noder: start writing implicit conversions + 2022-06-23 9cb784ac69 [dev.unified] cmd/compile/internal/noder: add pkgWriter.typeOf helper + 2022-06-23 c70e93ff3d [dev.unified] cmd/compile/internal/typecheck: replace unreachable code with assert + 2022-06-23 20e1d5ac8c [dev.unified] cmd/compile: special case f(g()) calls in Unified IR + 2022-06-23 61ae2b734c [dev.unified] cmd/compile: plumb rtype through OSWITCH/OCASE clauses + 2022-06-23 3d432b6c4b [dev.unified] cmd/compile: plumb rtype through for OMAPLIT + 2022-06-23 7368647ac6 [dev.unified] cmd/compile: start setting RType fields for Unified IR + 2022-06-23 5960f4ec10 [dev.unified] cmd/compile: add RType fields + 2022-06-21 5e0258c700 [dev.unified] cmd/compile: avoid reflectType in ssagen + 2022-06-21 93833cd5d8 [dev.unified] cmd/compile: extract rtype code from walk + 2022-06-21 f70775ff22 [dev.unified] cmd/compile: refactor reflectdata.{TypePtr,ITabAddr} + 2022-06-21 fc5dad6646 [dev.unified] cmd/compile/internal/walk: minor prep refactoring + 2022-06-16 1f4e8afafe [dev.unified] all: merge master (635b124) into dev.unified + 2022-06-15 8a9485c023 [dev.unified] test: extract different inline test between unified and non-unified + 2022-06-14 394ea70cc9 [dev.unified] cmd/compile: more Unified IR docs and review + 2022-06-10 f73ad3d24d [dev.unified] test: add regress tests for #53276 and #53328 + 2022-06-09 8ef8b60e18 [dev.unified] cmd/compile/internal/noder: stop handling type expressions as expressions + 2022-06-09 1a6c96bb9b [dev.unified] test: relax issue7921.go diagnostic message + 2022-06-09 c50c6bbc03 [dev.unified] cmd/compile: set base.Pos when process assignDef in Unified IR + 2022-06-09 d6df08693c [dev.unified] cmd/compile: fix unified IR don't report type size too large error + 2022-06-08 e7ef58542c [dev.unified] cmd/compile: restore Unified IR linkname pragma diagnostic + 2022-06-07 9e5c968021 [dev.unified] cmd/compile: visit LHS before RHS/X in assign/for statement + 2022-06-06 46ddf0873e [dev.unified] cmd/compile: export/import implicit attribute for conversion exprs + 2022-06-06 a8780f94c3 [dev.unified] cmd/compile: fix missing method value wrapper in unified IR + 2022-06-06 3a1f1e1575 [dev.unified] cmd/compile: remove package height + 2022-06-06 df7cb59de4 [dev.unified] cmd/compile: only sort symbols by name and package path + 2022-06-06 b39ac80871 [dev.unified] cmd/compile/internal/noder: push exprBlank up into assignment handling + 2022-06-06 55fc07e164 [dev.unified] cmd/compile/internal/noder: add optExpr for optional expressions + 2022-06-06 6c33f1d52e [dev.unified] cmd/compile/internal/noder: rename exprName to exprGlobal + 2022-06-06 4d28fcabb4 [dev.unified] all: update codereview.cfg for dev.unified branch Change-Id: I604d057735e8a365621c91c206f9e46eabb4679b
Diffstat (limited to 'src/cmd/compile/internal/noder/linker.go')
-rw-r--r--src/cmd/compile/internal/noder/linker.go107
1 files changed, 85 insertions, 22 deletions
diff --git a/src/cmd/compile/internal/noder/linker.go b/src/cmd/compile/internal/noder/linker.go
index a58b9b930c..0f39fdec05 100644
--- a/src/cmd/compile/internal/noder/linker.go
+++ b/src/cmd/compile/internal/noder/linker.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -34,13 +32,20 @@ import (
// low-level linking details can be moved there, but the logic for
// handling extension data needs to stay in the compiler.
+// A linker combines a package's stub export data with any referenced
+// elements from imported packages into a single, self-contained
+// export data file.
type linker struct {
pw pkgbits.PkgEncoder
- pkgs map[string]pkgbits.Index
- decls map[*types.Sym]pkgbits.Index
+ pkgs map[string]pkgbits.Index
+ decls map[*types.Sym]pkgbits.Index
+ bodies map[*types.Sym]pkgbits.Index
}
+// relocAll ensures that all elements specified by pr and relocs are
+// copied into the output export data file, and returns the
+// corresponding indices in the output.
func (l *linker) relocAll(pr *pkgReader, relocs []pkgbits.RelocEnt) []pkgbits.RelocEnt {
res := make([]pkgbits.RelocEnt, len(relocs))
for i, rent := range relocs {
@@ -50,6 +55,8 @@ func (l *linker) relocAll(pr *pkgReader, relocs []pkgbits.RelocEnt) []pkgbits.Re
return res
}
+// relocIdx ensures a single element is copied into the output export
+// data file, and returns the corresponding index in the output.
func (l *linker) relocIdx(pr *pkgReader, k pkgbits.RelocKind, idx pkgbits.Index) pkgbits.Index {
assert(pr != nil)
@@ -85,10 +92,19 @@ func (l *linker) relocIdx(pr *pkgReader, k pkgbits.RelocKind, idx pkgbits.Index)
return newidx
}
+// relocString copies the specified string from pr into the output
+// export data file, deduplicating it against other strings.
func (l *linker) relocString(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
return l.pw.StringIdx(pr.StringIdx(idx))
}
+// relocPkg copies the specified package from pr into the output
+// export data file, rewriting its import path to match how it was
+// imported.
+//
+// TODO(mdempsky): Since CL 391014, we already have the compilation
+// unit's import path, so there should be no need to rewrite packages
+// anymore.
func (l *linker) relocPkg(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
path := pr.PeekPkgPath(idx)
@@ -114,6 +130,9 @@ func (l *linker) relocPkg(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
return w.Flush()
}
+// relocObj copies the specified object from pr into the output export
+// data file, rewriting its compiler-private extension data (e.g.,
+// adding inlining cost and escape analysis results for functions).
func (l *linker) relocObj(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
path, name, tag := pr.PeekObj(idx)
sym := types.NewPkg(path, "").Lookup(name)
@@ -152,21 +171,12 @@ func (l *linker) relocObj(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
l.relocCommon(pr, &wname, pkgbits.RelocName, idx)
l.relocCommon(pr, &wdict, pkgbits.RelocObjDict, idx)
- var obj *ir.Name
- if sym.Pkg == types.LocalPkg {
- var ok bool
- obj, ok = sym.Def.(*ir.Name)
-
- // Generic types and functions and declared constraint types won't
- // have definitions.
- // For now, just generically copy their extension data.
- // TODO(mdempsky): Restore assertion.
- if !ok && false {
- base.Fatalf("missing definition for %v", sym)
- }
- }
+ // Generic types and functions won't have definitions, and imported
+ // objects may not either.
+ obj, _ := sym.Def.(*ir.Name)
+ local := sym.Pkg == types.LocalPkg
- if obj != nil {
+ if local && obj != nil {
wext.Sync(pkgbits.SyncObject1)
switch tag {
case pkgbits.ObjFunc:
@@ -181,9 +191,66 @@ func (l *linker) relocObj(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
l.relocCommon(pr, &wext, pkgbits.RelocObjExt, idx)
}
+ // Check if we need to export the inline bodies for functions and
+ // methods.
+ if obj != nil {
+ if obj.Op() == ir.ONAME && obj.Class == ir.PFUNC {
+ l.exportBody(obj, local)
+ }
+
+ if obj.Op() == ir.OTYPE {
+ if typ := obj.Type(); !typ.IsInterface() {
+ for _, method := range typ.Methods().Slice() {
+ l.exportBody(method.Nname.(*ir.Name), local)
+ }
+ }
+ }
+ }
+
return w.Idx
}
+// exportBody exports the given function or method's body, if
+// appropriate. local indicates whether it's a local function or
+// method available on a locally declared type. (Due to cross-package
+// type aliases, a method may be imported, but still available on a
+// locally declared type.)
+func (l *linker) exportBody(obj *ir.Name, local bool) {
+ assert(obj.Op() == ir.ONAME && obj.Class == ir.PFUNC)
+
+ fn := obj.Func
+ if fn.Inl == nil {
+ return // not inlinable anyway
+ }
+
+ // As a simple heuristic, if the function was declared in this
+ // package or we inlined it somewhere in this package, then we'll
+ // (re)export the function body. This isn't perfect, but seems
+ // reasonable in practice. In particular, it has the nice property
+ // that in the worst case, adding a blank import ensures the
+ // function body is available for inlining.
+ //
+ // TODO(mdempsky): Reimplement the reachable method crawling logic
+ // from typecheck/crawler.go.
+ exportBody := local || fn.Inl.Body != nil
+ if !exportBody {
+ return
+ }
+
+ sym := obj.Sym()
+ if _, ok := l.bodies[sym]; ok {
+ // Due to type aliases, we might visit methods multiple times.
+ base.AssertfAt(obj.Type().Recv() != nil, obj.Pos(), "expected method: %v", obj)
+ return
+ }
+
+ pri, ok := bodyReaderFor(fn)
+ assert(ok)
+ l.bodies[sym] = l.relocIdx(pri.pr, pkgbits.RelocBody, pri.idx)
+}
+
+// relocCommon copies the specified element from pr into w,
+// recursively relocating any referenced elements as well.
func (l *linker) relocCommon(pr *pkgReader, w *pkgbits.Encoder, k pkgbits.RelocKind, idx pkgbits.Index) {
r := pr.NewDecoderRaw(k, idx)
w.Relocs = l.relocAll(pr, r.Relocs)
@@ -220,10 +287,6 @@ func (l *linker) relocFuncExt(w *pkgbits.Encoder, name *ir.Name) {
if inl := name.Func.Inl; w.Bool(inl != nil) {
w.Len(int(inl.Cost))
w.Bool(inl.CanDelayResults)
-
- pri, ok := bodyReader[name.Func]
- assert(ok)
- w.Reloc(pkgbits.RelocBody, l.relocIdx(pri.pr, pkgbits.RelocBody, pri.idx))
}
w.Sync(pkgbits.SyncEOF)