]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: store types.Field on {Selector,CallPart}Expr
authorMatthew Dempsky <mdempsky@google.com>
Thu, 3 Dec 2020 05:38:20 +0000 (21:38 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 3 Dec 2020 19:33:13 +0000 (19:33 +0000)
It's useful to have quick access to the types.Field that a given
selector or method value expression refer to. Previously we abused Opt
for this, but couldn't do that for OCALLPART because escape analysis
uses Opt.

Now that we have more flexibility, we can simply add additional
pointer fields for this. This also allows getting rid of an unneeded
ONAME node for OCALLPART.

Passes buildall w/ toolstash -cmp.

Change-Id: I980d7bdb19abfd0b6f58a232876861b88dee1e47
Reviewed-on: https://go-review.googlesource.com/c/go/+/275034
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/gc/closure.go
src/cmd/compile/internal/gc/iexport.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/ir/expr.go
src/cmd/compile/internal/ir/fmt.go

index a5441a037a0bba513baddf819a2c92609120139b..01e5a953de8d52f894cbe85b648b07992c8c75f8 100644 (file)
@@ -427,7 +427,7 @@ func typecheckpartialcall(dot ir.Node, sym *types.Sym) *ir.CallPartExpr {
        fn := makepartialcall(dot, dot.Type(), sym)
        fn.SetWrapper(true)
 
-       return ir.NewCallPartExpr(dot.Pos(), dot.Left(), NewName(sym), fn)
+       return ir.NewCallPartExpr(dot.Pos(), dot.Left(), dot.(*ir.SelectorExpr).Selection, fn)
 }
 
 // makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
@@ -565,16 +565,5 @@ func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node {
 // callpartMethod returns the *types.Field representing the method
 // referenced by method value n.
 func callpartMethod(n ir.Node) *types.Field {
-       if n.Op() != ir.OCALLPART {
-               base.Fatalf("expected OCALLPART, got %v", n)
-       }
-
-       // TODO(mdempsky): Optimize this. If necessary,
-       // makepartialcall could save m for us somewhere.
-       var m *types.Field
-       if lookdot0(n.Right().Sym(), n.Left().Type(), &m, false) != 1 {
-               base.Fatalf("failed to find field for OCALLPART")
-       }
-
-       return m
+       return n.(*ir.CallPartExpr).Method
 }
index 85518bc9391a1251bf3fa51f896fdd18a18b32bd..bb6f2b11e62e4b26f02321acddab2d7707d6bf6a 100644 (file)
@@ -1290,8 +1290,7 @@ func (w *exportWriter) expr(n ir.Node) {
                w.op(ir.OXDOT)
                w.pos(n.Pos())
                w.expr(n.Left())
-               // Right node should be ONAME
-               w.selector(n.Right().Sym())
+               w.selector(n.Sym())
 
        case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH:
                w.op(ir.OXDOT)
index 42125f38f3e27b10d75913977d9c7889a0f8149a..64f1b062be57d7174faaead68db39a9ce3aff1a1 100644 (file)
@@ -430,6 +430,9 @@ func (v *hairyVisitor) visit(n ir.Node) bool {
                // In any event, let the visitList(n.List()) below take care of the statements,
                // and don't charge for the OBLOCK itself. The ++ undoes the -- below.
                v.budget++
+
+       case ir.OCALLPART:
+               v.budget-- // Hack for toolstash -cmp.
        }
 
        v.budget--
index b19481311b6c11aef807d6b1bb9633ad8731f134..e2100481aa6fa1b02d71405c47a82d6db8c1fb38 100644 (file)
@@ -2385,7 +2385,7 @@ func typecheckMethodExpr(n ir.Node) (res ir.Node) {
        me.SetType(methodfunc(m.Type, n.Left().Type()))
        me.SetOffset(0)
        me.SetClass(ir.PFUNC)
-       me.SetOpt(m)
+       me.(*ir.MethodExpr).Method = m
 
        // Issue 25065. Make sure that we emit the symbol for a local method.
        if base.Ctxt.Flag_dynlink && !inimport && (t.Sym() == nil || t.Sym().Pkg == ir.LocalPkg) {
@@ -2448,10 +2448,8 @@ func lookdot(n ir.Node, t *types.Type, dostrcmp int) *types.Field {
                        }
 
                        n.SetOp(ir.ODOTINTER)
-               } else {
-                       n.SetOpt(f1)
                }
-
+               n.(*ir.SelectorExpr).Selection = f1
                return f1
        }
 
@@ -2507,7 +2505,7 @@ func lookdot(n ir.Node, t *types.Type, dostrcmp int) *types.Field {
                n.SetOffset(f2.Offset)
                n.SetType(f2.Type)
                n.SetOp(ir.ODOTMETH)
-               n.SetOpt(f2)
+               n.(*ir.SelectorExpr).Selection = f2
 
                return f2
        }
@@ -3933,8 +3931,10 @@ func methodExprName(n ir.Node) *ir.Name {
 // MethodFunc is like MethodName, but returns the types.Field instead.
 func methodExprFunc(n ir.Node) *types.Field {
        switch n.Op() {
-       case ir.ODOTMETH, ir.OMETHEXPR:
-               return n.Opt().(*types.Field)
+       case ir.ODOTMETH:
+               return n.(*ir.SelectorExpr).Selection
+       case ir.OMETHEXPR:
+               return n.(*ir.MethodExpr).Method
        case ir.OCALLPART:
                return callpartMethod(n)
        }
index ce7de1396b34532e8c317f4d2de10e595ab766e2..3d22c66d901c5c6d50a65b6ef079306c57970d84 100644 (file)
@@ -3757,7 +3757,7 @@ func usefield(n ir.Node) {
        if t.IsPtr() {
                t = t.Elem()
        }
-       field := n.Opt().(*types.Field)
+       field := n.(*ir.SelectorExpr).Selection
        if field == nil {
                base.Fatalf("usefield %v %v without paramfld", n.Left().Type(), n.Sym())
        }
index 412b7a18f014a02d7d9f543475d71d94f763d05d..18d85a01df8dfabee63c6b738e169015ecf060a8 100644 (file)
@@ -205,10 +205,10 @@ type CallPartExpr struct {
        miniExpr
        fn     *Func
        X      Node
-       Method *Name
+       Method *types.Field
 }
 
-func NewCallPartExpr(pos src.XPos, x Node, method *Name, fn *Func) *CallPartExpr {
+func NewCallPartExpr(pos src.XPos, x Node, method *types.Field, fn *Func) *CallPartExpr {
        n := &CallPartExpr{fn: fn, X: x, Method: method}
        n.op = OCALLPART
        n.pos = pos
@@ -222,9 +222,8 @@ func (n *CallPartExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
 func (n *CallPartExpr) rawCopy() Node                 { c := *n; return &c }
 func (n *CallPartExpr) Func() *Func                   { return n.fn }
 func (n *CallPartExpr) Left() Node                    { return n.X }
-func (n *CallPartExpr) Right() Node                   { return n.Method }
+func (n *CallPartExpr) Sym() *types.Sym               { return n.Method.Sym }
 func (n *CallPartExpr) SetLeft(x Node)                { n.X = x }
-func (n *CallPartExpr) SetRight(x Node)               { n.Method = x.(*Name) }
 
 // A ClosureExpr is a function literal expression.
 type ClosureExpr struct {
@@ -499,6 +498,7 @@ type MethodExpr struct {
        sym    *types.Sym
        offset int64
        class  Class
+       Method *types.Field
 }
 
 func NewMethodExpr(pos src.XPos, op Op, x, m Node) *MethodExpr {
@@ -596,9 +596,10 @@ func (n *ResultExpr) SetOffset(x int64)             { n.offset = x }
 // A SelectorExpr is a selector expression X.Sym.
 type SelectorExpr struct {
        miniExpr
-       X      Node
-       Sel    *types.Sym
-       offset int64
+       X         Node
+       Sel       *types.Sym
+       offset    int64
+       Selection *types.Field
 }
 
 func NewSelectorExpr(pos src.XPos, x Node, sel *types.Sym) *SelectorExpr {
index 9486d8b021d5400457fe820ab66585360a2b08a2..45a66a2290925a554a5399334d06b9935be1e12f 100644 (file)
@@ -1382,11 +1382,11 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
 
        case OCALLPART:
                exprFmt(n.Left(), s, nprec, mode)
-               if n.Right() == nil || n.Right().Sym() == nil {
+               if n.Sym() == nil {
                        fmt.Fprint(s, ".<nil>")
                        return
                }
-               mode.Fprintf(s, ".%0S", n.Right().Sym())
+               mode.Fprintf(s, ".%0S", n.Sym())
 
        case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
                exprFmt(n.Left(), s, nprec, mode)