]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: only access Func method on concrete types
authorRuss Cox <rsc@golang.org>
Mon, 21 Dec 2020 20:10:26 +0000 (15:10 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 22 Dec 2020 19:32:21 +0000 (19:32 +0000)
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 <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
14 files changed:
src/cmd/compile/internal/gc/closure.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/escape.go
src/cmd/compile/internal/gc/iimport.go
src/cmd/compile/internal/gc/initorder.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/scc.go
src/cmd/compile/internal/gc/scope.go
src/cmd/compile/internal/gc/sinit.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/ir/fmt.go
src/cmd/compile/internal/ir/func.go

index e07ed4cd248304ef4fd28492b7fc6d6d84663cbc..1f4bf969adad609bf78a825e1665fc29bbb2c329 100644 (file)
@@ -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,
index bcd127b5f17c98691951dd1ce082919995501f5b..558bdbef9241d5ee8a9934c3b5d73574cd09654d 100644 (file)
@@ -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)
index 3351cfe968dada1c926c8fcbe563bed588216284..6510dfc4b3d3c294a1a8c1b45f34c6fafb8e1ff7 100644 (file)
@@ -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 {
index 358fdef294d3f6f37a7af0f2a3e1183c737a7db6..5f72cedb669d7fe225da65823be86ce44e963059 100644 (file)
@@ -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) {
index 1b21d92f4b7b3f494e32df3b41da71081b49e9f2..c9c3361d3cf8197db30046d3b2e3cb0bc933995b 100644 (file)
@@ -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:
index fde4d6910adabd5ada234c622f7717fa3cc3cea9..fc020000c774a51ebf0067df9c251b5bcb46a26f 100644 (file)
@@ -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
index 80b17ebbf80d37ff28a3452346c15f7f5ef2746d..94b4e0e674e82f8ae6a6b577d19c18eb667227a9 100644 (file)
@@ -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)
+                       }
                }
        }
 
index 6e63d5287a2773793a166c41ab3c8b72ec990fef..8fe20a80fd9926836a38682d7b5d75f56b8deed1 100644 (file)
@@ -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
                        }
index fe4e1d185ad14b9b2751423d6b0ed9e2a3ac2181..8dd44b1dd45135efca124802a7e3df9e233d283e 100644 (file)
@@ -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 {
index 9ef2bd56ebabefd9e02eb24628f434d94c07f805..79c7215d4d438659338b01d70a7ec03e13cb93ed 100644 (file)
@@ -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")
index cc5df3ebaef3e8bab4f661afbbeddef8abf732d1..bb658999e58a52bb140edf1a28e4b60fdba560b5 100644 (file)
@@ -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
index 5545dcb3453df1628eb10df67ae837c4553fe8b7..87f08f41c363a24bfeffbbbf0a1c09447eae1c74 100644 (file)
@@ -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.
index 6f15645813e5147e30fa4e89f3e57650b857186a..76bb35f971f65bfe915db994feccdf9a621ea8bb 100644 (file)
@@ -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()
index 8aa6daed6fc51953fbcfa133838d8fef74f51328..62ac5791d1a2aef6c14559718e91de71d6b34f84 100644 (file)
@@ -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 "<nil>"
        }
-       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 "<nil>"
                }
-               s = n.Func().Nname.Sym()
+               s = f.Nname.Sym()
        }
        pkg := s.Pkg