diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2023-08-24 03:04:01 -0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-08-24 23:19:42 +0000 |
| commit | 88cb17e1069bef854ead49c703262abdf93c9458 (patch) | |
| tree | 521b48c02ad60fecddeca0dce59b547c3065c4e2 /src/cmd/compile/internal/noder/reader.go | |
| parent | cf6838467453be54d1c6b45f431db35cf95b1eee (diff) | |
| download | go-88cb17e1069bef854ead49c703262abdf93c9458.tar.xz | |
cmd/compile: create "init" function during noding
This CL arranges for package-scope initialization statements to be
constructed directly into their eventual "init" function, so we can
eliminate the roundabout solution of using InitTodoFunc.
While here, somewhat simplify and generalize the logic for outlining
map initialization statements.
Change-Id: I8aff042e6b266f7024de436424ec6711b8b69129
Reviewed-on: https://go-review.googlesource.com/c/go/+/522318
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder/reader.go')
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 77 |
1 files changed, 34 insertions, 43 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index 0efe2ea2d5..01f001f199 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -2988,52 +2988,12 @@ func (r *reader) multiExpr() []ir.Node { // temp returns a new autotemp of the specified type. func (r *reader) temp(pos src.XPos, typ *types.Type) *ir.Name { - // See typecheck.typecheckargs. - curfn := r.curfn - if curfn == nil { - curfn = typecheck.InitTodoFunc - } - - return typecheck.TempAt(pos, curfn, typ) + return typecheck.TempAt(pos, r.curfn, typ) } // tempCopy declares and returns a new autotemp initialized to the // value of expr. func (r *reader) tempCopy(pos src.XPos, expr ir.Node, init *ir.Nodes) *ir.Name { - if r.curfn == nil { - // Escape analysis doesn't know how to handle package-scope - // function literals with free variables (i.e., that capture - // temporary variables added to typecheck.InitTodoFunc). - // - // stencil.go works around this limitation by spilling values to - // global variables instead, but that causes the value to stay - // alive indefinitely; see go.dev/issue/54343. - // - // This code path (which implements the same workaround) isn't - // actually needed by unified IR, because it creates uses normal - // OMETHEXPR/OMETHVALUE nodes when statically-known instantiated - // types are used. But it's kept around for now because it's handy - // for testing that the generic fallback paths work correctly. - base.Fatalf("tempCopy called at package scope") - - tmp := staticinit.StaticName(expr.Type()) - - assign := ir.NewAssignStmt(pos, tmp, expr) - assign.Def = true - tmp.Defn = assign - - // TODO(mdempsky): This code doesn't work anymore, because we now - // rely on types2 to compute InitOrder. If it's going to be used - // for testing again, the assignment here probably needs to be - // added to typecheck.Target.InitOrder somewhere. - // - // Probably just easier to address the escape analysis limitation. - // - // typecheck.Target.Decls = append(typecheck.Target.Decls, typecheck.Stmt(assign)) - - return tmp - } - tmp := r.temp(pos, expr.Type()) init.Append(typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp))) @@ -3328,9 +3288,32 @@ func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) { } target.CgoPragmas = cgoPragmas + r.pkgInitOrder(target) + r.pkgDecls(target) + r.Sync(pkgbits.SyncEOF) +} + +// pkgInitOrder creates a synthetic init function to handle any +// package-scope initialization statements. +func (r *reader) pkgInitOrder(target *ir.Package) { initOrder := make([]ir.Node, r.Len()) + if len(initOrder) == 0 { + return + } + + // Make a function that contains all the initialization statements. + pos := base.AutogeneratedPos + base.Pos = pos + + fn := ir.NewFunc(pos, pos, typecheck.Lookup("init"), types.NewSignature(nil, nil, nil)) + fn.SetIsPackageInit(true) + fn.SetInlinabilityChecked(true) // suppress useless "can inline" diagnostics + + typecheck.DeclFunc(fn) + r.curfn = fn + for i := range initOrder { lhs := make([]ir.Node, r.Len()) for j := range lhs { @@ -3352,9 +3335,17 @@ func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) { initOrder[i] = as } - target.InitOrder = initOrder - r.Sync(pkgbits.SyncEOF) + fn.Body = initOrder + + typecheck.FinishFuncBody() + r.curfn = nil + r.locals = nil + + // Outline (if legal/profitable) global map inits. + staticinit.OutlineMapInits(fn) + + target.Inits = append(target.Inits, fn) } func (r *reader) pkgDecls(target *ir.Package) { |
