From 280e7fd1ee47ad92b0031bbc0fa103ac25552950 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 21 Dec 2020 15:10:26 -0500 Subject: [PATCH] [dev.regabi] cmd/compile: only access Func method on concrete types Sets up for removing Func from Node interface. That means that once the Name reorg is done, which will let us remove Name, Sym, and Val, Node will be basically a minimal interface. Passes buildall w/ toolstash -cmp. Change-Id: I6e87897572debd7f8e29b4f5167763dc2792b408 Reviewed-on: https://go-review.googlesource.com/c/go/+/279484 Trust: Russ Cox Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/closure.go | 8 +++---- src/cmd/compile/internal/gc/dcl.go | 1 + src/cmd/compile/internal/gc/escape.go | 5 +++-- src/cmd/compile/internal/gc/iimport.go | 4 ++-- src/cmd/compile/internal/gc/initorder.go | 1 + src/cmd/compile/internal/gc/inl.go | 3 ++- src/cmd/compile/internal/gc/main.go | 9 +++++--- src/cmd/compile/internal/gc/scc.go | 8 +++++-- src/cmd/compile/internal/gc/scope.go | 2 +- src/cmd/compile/internal/gc/sinit.go | 1 + src/cmd/compile/internal/gc/typecheck.go | 10 ++++++--- src/cmd/compile/internal/gc/walk.go | 7 +++--- src/cmd/compile/internal/ir/fmt.go | 1 + src/cmd/compile/internal/ir/func.go | 28 ++++++++++++++++++++---- 14 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index e07ed4cd24..1f4bf969ad 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -76,7 +76,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node { // function associated with the closure. // TODO: This creation of the named function should probably really be done in a // separate pass from type-checking. -func typecheckclosure(clo ir.Node, top int) { +func typecheckclosure(clo *ir.ClosureExpr, top int) { fn := clo.Func() // Set current associated iota value, so iota can be used inside // function in ConstSpec, see issue #22344 @@ -327,13 +327,13 @@ func transformclosure(fn *ir.Func) { // hasemptycvars reports whether closure clo has an // empty list of captured vars. -func hasemptycvars(clo ir.Node) bool { +func hasemptycvars(clo *ir.ClosureExpr) bool { return len(clo.Func().ClosureVars) == 0 } // closuredebugruntimecheck applies boilerplate checks for debug flags // and compiling runtime -func closuredebugruntimecheck(clo ir.Node) { +func closuredebugruntimecheck(clo *ir.ClosureExpr) { if base.Debug.Closure > 0 { if clo.Esc() == EscHeap { base.WarnfAt(clo.Pos(), "heap closure, captured vars = %v", clo.Func().ClosureVars) @@ -349,7 +349,7 @@ func closuredebugruntimecheck(clo ir.Node) { // closureType returns the struct type used to hold all the information // needed in the closure for clo (clo must be a OCLOSURE node). // The address of a variable of the returned type can be cast to a func. -func closureType(clo ir.Node) *types.Type { +func closureType(clo *ir.ClosureExpr) *types.Type { // Create closure in the form of a composite literal. // supposing the closure captures an int i and a string s // and has one float64 argument and no results, diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index bcd127b5f1..558bdbef92 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -892,6 +892,7 @@ func (c *nowritebarrierrecChecker) findExtraCalls(nn ir.Node) { case ir.ONAME: callee = arg.Name().Defn.(*ir.Func) case ir.OCLOSURE: + arg := arg.(*ir.ClosureExpr) callee = arg.Func() default: base.Fatalf("expected ONAME or OCLOSURE node, got %+v", arg) diff --git a/src/cmd/compile/internal/gc/escape.go b/src/cmd/compile/internal/gc/escape.go index 3351cfe968..6510dfc4b3 100644 --- a/src/cmd/compile/internal/gc/escape.go +++ b/src/cmd/compile/internal/gc/escape.go @@ -678,6 +678,7 @@ func (e *Escape) exprSkipInit(k EscHole, n ir.Node) { } case ir.OCLOSURE: + n := n.(*ir.ClosureExpr) k = e.spill(k, n) // Link addresses of captured variables to closure. @@ -879,7 +880,7 @@ func (e *Escape) call(ks []EscHole, call, where ir.Node) { case v.Op() == ir.ONAME && v.(*ir.Name).Class() == ir.PFUNC: fn = v.(*ir.Name) case v.Op() == ir.OCLOSURE: - fn = v.Func().Nname + fn = v.(*ir.ClosureExpr).Func().Nname } case ir.OCALLMETH: fn = methodExprName(call.Left()) @@ -1883,7 +1884,7 @@ func heapAllocReason(n ir.Node) string { return "too large for stack" } - if n.Op() == ir.OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize { + if n.Op() == ir.OCLOSURE && closureType(n.(*ir.ClosureExpr)).Size() >= maxImplicitStackVarSize { return "too large for stack" } if n.Op() == ir.OCALLPART && partialCallType(n.(*ir.CallPartExpr)).Size() >= maxImplicitStackVarSize { diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go index 358fdef294..5f72cedb66 100644 --- a/src/cmd/compile/internal/gc/iimport.go +++ b/src/cmd/compile/internal/gc/iimport.go @@ -630,7 +630,7 @@ func (r *importReader) varExt(n ir.Node) { r.symIdx(n.Sym()) } -func (r *importReader) funcExt(n ir.Node) { +func (r *importReader) funcExt(n *ir.Name) { r.linkname(n.Sym()) r.symIdx(n.Sym()) @@ -654,7 +654,7 @@ func (r *importReader) methExt(m *types.Field) { if r.bool() { m.SetNointerface(true) } - r.funcExt(ir.AsNode(m.Nname)) + r.funcExt(m.Nname.(*ir.Name)) } func (r *importReader) linkname(s *types.Sym) { diff --git a/src/cmd/compile/internal/gc/initorder.go b/src/cmd/compile/internal/gc/initorder.go index 1b21d92f4b..c9c3361d3c 100644 --- a/src/cmd/compile/internal/gc/initorder.go +++ b/src/cmd/compile/internal/gc/initorder.go @@ -296,6 +296,7 @@ func (d *initDeps) visit(n ir.Node) { } case ir.OCLOSURE: + n := n.(*ir.ClosureExpr) d.inspectList(n.Func().Body()) case ir.ODOTMETH, ir.OCALLPART: diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index fde4d6910a..fc020000c7 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -237,7 +237,7 @@ func caninl(fn *ir.Func) { n.Func().Inl = &ir.Inline{ Cost: inlineMaxBudget - visitor.budget, - Dcl: pruneUnusedAutos(n.Defn.Func().Dcl, &visitor), + Dcl: pruneUnusedAutos(n.Defn.(*ir.Func).Func().Dcl, &visitor), Body: ir.DeepCopyList(src.NoXPos, fn.Body().Slice()), } @@ -677,6 +677,7 @@ func inlCallee(fn ir.Node) *ir.Func { return fn.Func() } case ir.OCLOSURE: + fn := fn.(*ir.ClosureExpr) c := fn.Func() caninl(c) return c diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index 80b17ebbf8..94b4e0e674 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -270,9 +270,12 @@ func Main(archInit func(*Arch)) { // before walk reaches a call of a closure. timings.Start("fe", "xclosures") for _, n := range Target.Decls { - if n.Op() == ir.ODCLFUNC && n.Func().OClosure != nil { - Curfn = n.(*ir.Func) - transformclosure(Curfn) + if n.Op() == ir.ODCLFUNC { + n := n.(*ir.Func) + if n.Func().OClosure != nil { + Curfn = n + transformclosure(n) + } } } diff --git a/src/cmd/compile/internal/gc/scc.go b/src/cmd/compile/internal/gc/scc.go index 6e63d5287a..8fe20a80fd 100644 --- a/src/cmd/compile/internal/gc/scc.go +++ b/src/cmd/compile/internal/gc/scc.go @@ -56,8 +56,11 @@ func visitBottomUp(list []ir.Node, analyze func(list []*ir.Func, recursive bool) v.analyze = analyze v.nodeID = make(map[*ir.Func]uint32) for _, n := range list { - if n.Op() == ir.ODCLFUNC && !n.Func().IsHiddenClosure() { - v.visit(n.(*ir.Func)) + if n.Op() == ir.ODCLFUNC { + n := n.(*ir.Func) + if !n.Func().IsHiddenClosure() { + v.visit(n) + } } } } @@ -109,6 +112,7 @@ func (v *bottomUpVisitor) visit(n *ir.Func) uint32 { } } case ir.OCLOSURE: + n := n.(*ir.ClosureExpr) if m := v.visit(n.Func()); m < min { min = m } diff --git a/src/cmd/compile/internal/gc/scope.go b/src/cmd/compile/internal/gc/scope.go index fe4e1d185a..8dd44b1dd4 100644 --- a/src/cmd/compile/internal/gc/scope.go +++ b/src/cmd/compile/internal/gc/scope.go @@ -28,7 +28,7 @@ func findScope(marks []ir.Mark, pos src.XPos) ir.ScopeID { return marks[i-1].Scope } -func assembleScopes(fnsym *obj.LSym, fn ir.Node, dwarfVars []*dwarf.Var, varScopes []ir.ScopeID) []dwarf.Scope { +func assembleScopes(fnsym *obj.LSym, fn *ir.Func, dwarfVars []*dwarf.Var, varScopes []ir.ScopeID) []dwarf.Scope { // Initialize the DWARF scope tree based on lexical scopes. dwarfScopes := make([]dwarf.Scope, 1+len(fn.Func().Parents)) for i, parent := range fn.Func().Parents { diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go index 9ef2bd56eb..79c7215d4d 100644 --- a/src/cmd/compile/internal/gc/sinit.go +++ b/src/cmd/compile/internal/gc/sinit.go @@ -269,6 +269,7 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type break case ir.OCLOSURE: + r := r.(*ir.ClosureExpr) if hasemptycvars(r) { if base.Debug.Closure > 0 { base.WarnfAt(r.Pos(), "closure converted to global") diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index cc5df3ebae..bb658999e5 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -95,9 +95,12 @@ func TypecheckPackage() { // because variables captured by value do not escape. timings.Start("fe", "capturevars") for _, n := range Target.Decls { - if n.Op() == ir.ODCLFUNC && n.Func().OClosure != nil { - Curfn = n.(*ir.Func) - capturevars(Curfn) + if n.Op() == ir.ODCLFUNC { + n := n.(*ir.Func) + if n.Func().OClosure != nil { + Curfn = n + capturevars(n) + } } } capturevarscomplete = true @@ -2078,6 +2081,7 @@ func typecheck1(n ir.Node, top int) (res ir.Node) { return n case ir.OCLOSURE: + n := n.(*ir.ClosureExpr) typecheckclosure(n, top) if n.Type() == nil { return n diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 5545dcb345..87f08f41c3 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -649,11 +649,12 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node { // transformclosure already did all preparation work. // Prepend captured variables to argument list. - n.PtrList().Prepend(n.Left().Func().ClosureEnter.Slice()...) - n.Left().Func().ClosureEnter.Set(nil) + clo := n.Left().(*ir.ClosureExpr) + n.PtrList().Prepend(clo.Func().ClosureEnter.Slice()...) + clo.Func().ClosureEnter.Set(nil) // Replace OCLOSURE with ONAME/PFUNC. - n.SetLeft(n.Left().Func().Nname) + n.SetLeft(clo.Func().Nname) // Update type of OCALLFUNC node. // Output arguments had not changed, but their offsets could. diff --git a/src/cmd/compile/internal/ir/fmt.go b/src/cmd/compile/internal/ir/fmt.go index 6f15645813..76bb35f971 100644 --- a/src/cmd/compile/internal/ir/fmt.go +++ b/src/cmd/compile/internal/ir/fmt.go @@ -1189,6 +1189,7 @@ func dumpNode(w io.Writer, n Node, depth int) { case ODCLFUNC: // Func has many fields we don't want to print. // Bypass reflection and just print what we want. + n := n.(*Func) fmt.Fprintf(w, "%+v", n.Op()) dumpNodeHeader(w, n) fn := n.Func() diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go index 8aa6daed6f..62ac5791d1 100644 --- a/src/cmd/compile/internal/ir/func.go +++ b/src/cmd/compile/internal/ir/func.go @@ -213,10 +213,21 @@ func (f *Func) SetWBPos(pos src.XPos) { // funcname returns the name (without the package) of the function n. func FuncName(n Node) string { - if n == nil || n.Func() == nil || n.Func().Nname == nil { + var f *Func + switch n := n.(type) { + case *Func: + f = n + case *Name: + f = n.Func() + case *CallPartExpr: + f = n.Func() + case *ClosureExpr: + f = n.Func() + } + if f == nil || f.Nname == nil { return "" } - return n.Func().Nname.Sym().Name + return f.Nname.Sym().Name } // pkgFuncName returns the name of the function referenced by n, with package prepended. @@ -231,10 +242,19 @@ func PkgFuncName(n Node) string { if n.Op() == ONAME { s = n.Sym() } else { - if n.Func() == nil || n.Func().Nname == nil { + var f *Func + switch n := n.(type) { + case *CallPartExpr: + f = n.Func() + case *ClosureExpr: + f = n.Func() + case *Func: + f = n + } + if f == nil || f.Nname == nil { return "" } - s = n.Func().Nname.Sym() + s = f.Nname.Sym() } pkg := s.Pkg -- 2.48.1