mirror of
https://github.com/golang/go
synced 2024-11-26 02:57:57 -07:00
[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 <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
51ba53f5c2
commit
280e7fd1ee
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user