aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/inline
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-06-11 03:09:26 -0700
committerMatthew Dempsky <mdempsky@google.com>2021-06-12 13:53:19 +0000
commit0132b91127c3cf6e19e0e1db014a04219427171e (patch)
tree577fb27f75e4b57916072c31f343bde8f8a6aefc /src/cmd/compile/internal/inline
parent8f00eb009978e2e1bb681e698a0b51e20333eb05 (diff)
downloadgo-0132b91127c3cf6e19e0e1db014a04219427171e.tar.gz
go-0132b91127c3cf6e19e0e1db014a04219427171e.zip
[dev.typeparams] cmd/compile: refactor closure construction
typecheck.tcClosure is complicated with many code flows because all of its callers setup the closure funcs in slightly different ways. E.g., it's non-obvious who's responsible for setting the underlying func's Sym or adding it to target.Decls, or how to write new code that constructs a closure without interfering with existing code. This CL refactors everything to use three common functions in package ir: NewClosureFunc (which handle creating the Func, Name, and ClosureExpr and wiring them together), NameClosure (which generates and assigns its unique Sym), and UseClosure (which handles adding the Func to target.Decls). Most IR builders can actually name the closure right away, but the legacy noder+typecheck path may not yet know the name of the enclosing function. In particular, for methods declared with aliased receiver parameters, we need to wait until after typechecking top-level declarations to know the method's true name. So they're left anonymous until typecheck. UseClosure does relatively little work today, but it serves as a useful spot to check that the code setting up closures got it right. It may also eventually serve as an optimization point for early lifting of trivial closures, which may or may not ultimately be beneficial. Change-Id: I7da1e93c70d268f575b12d6aaeb2336eb910a6f1 Reviewed-on: https://go-review.googlesource.com/c/go/+/327051 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Diffstat (limited to 'src/cmd/compile/internal/inline')
-rw-r--r--src/cmd/compile/internal/inline/inl.go32
1 files changed, 11 insertions, 21 deletions
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
index e12a30f936..76a15dab8b 100644
--- a/src/cmd/compile/internal/inline/inl.go
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -1143,8 +1143,6 @@ func (subst *inlsubst) clovar(n *ir.Name) *ir.Name {
// closure does the necessary substitions for a ClosureExpr n and returns the new
// closure node.
func (subst *inlsubst) closure(n *ir.ClosureExpr) ir.Node {
- m := ir.Copy(n)
-
// Prior to the subst edit, set a flag in the inlsubst to
// indicated that we don't want to update the source positions in
// the new closure. If we do this, it will appear that the closure
@@ -1152,29 +1150,21 @@ func (subst *inlsubst) closure(n *ir.ClosureExpr) ir.Node {
// issue #46234 for more details.
defer func(prev bool) { subst.noPosUpdate = prev }(subst.noPosUpdate)
subst.noPosUpdate = true
- ir.EditChildren(m, subst.edit)
//fmt.Printf("Inlining func %v with closure into %v\n", subst.fn, ir.FuncName(ir.CurFunc))
- // The following is similar to funcLit
+ outerfunc := subst.newclofn
+ if outerfunc == nil {
+ outerfunc = ir.CurFunc
+ }
+
oldfn := n.Func
- newfn := ir.NewFunc(oldfn.Pos())
- // These three lines are not strictly necessary, but just to be clear
- // that new function needs to redo typechecking and inlinability.
- newfn.SetTypecheck(0)
- newfn.SetInlinabilityChecked(false)
- newfn.Inl = nil
- newfn.SetIsHiddenClosure(true)
- newfn.Nname = ir.NewNameAt(n.Pos(), ir.BlankNode.Sym())
- newfn.Nname.Func = newfn
+ newfn := ir.NewClosureFunc(oldfn.Pos(), outerfunc)
+
// Ntype can be nil for -G=3 mode.
if oldfn.Nname.Ntype != nil {
newfn.Nname.Ntype = subst.node(oldfn.Nname.Ntype).(ir.Ntype)
}
- newfn.Nname.Defn = newfn
-
- m.(*ir.ClosureExpr).Func = newfn
- newfn.OClosure = m.(*ir.ClosureExpr)
if subst.newclofn != nil {
//fmt.Printf("Inlining a closure with a nested closure\n")
@@ -1224,13 +1214,13 @@ func (subst *inlsubst) closure(n *ir.ClosureExpr) ir.Node {
// Actually create the named function for the closure, now that
// the closure is inlined in a specific function.
- m.SetTypecheck(0)
+ newclo := newfn.OClosure
+ newclo.SetInit(subst.list(n.Init()))
if oldfn.ClosureCalled() {
- typecheck.Callee(m)
+ return typecheck.Callee(newclo)
} else {
- typecheck.Expr(m)
+ return typecheck.Expr(newclo)
}
- return m
}
// node recursively copies a node from the saved pristine body of the