]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: remove {Ptr,Set}Init from Node interface
authorMatthew Dempsky <mdempsky@google.com>
Sat, 2 Jan 2021 09:04:19 +0000 (01:04 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Sat, 2 Jan 2021 10:57:23 +0000 (10:57 +0000)
This CL separates out PtrInit and SetInit into a new InitNode
extension interface, and adds a new TakeInit helper function for
taking and clearing the Init list (if any) from a Node.

This allows removing miniNode.SetInit and miniNode.PtrInit, which in
turn allow getting rid of immutableEmptyNodes, and will allow
simplification of the Nodes API.

It would be nice to get rid of the default Init method too, but
there's way more code that expects to be able to call that at the
moment, so that'll have to wait.

Passes toolstash -cmp.

Change-Id: Ia8c18fab9555b774376f7f43eeecfde4f07b5946
Reviewed-on: https://go-review.googlesource.com/c/go/+/281001
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>
14 files changed:
src/cmd/compile/internal/deadcode/deadcode.go
src/cmd/compile/internal/inline/inl.go
src/cmd/compile/internal/ir/mini.go
src/cmd/compile/internal/ir/node.go
src/cmd/compile/internal/noder/noder.go
src/cmd/compile/internal/typecheck/typecheck.go
src/cmd/compile/internal/walk/assign.go
src/cmd/compile/internal/walk/builtin.go
src/cmd/compile/internal/walk/expr.go
src/cmd/compile/internal/walk/order.go
src/cmd/compile/internal/walk/range.go
src/cmd/compile/internal/walk/select.go
src/cmd/compile/internal/walk/stmt.go
src/cmd/compile/internal/walk/walk.go

index 5453cfe396b2a4875c5ec5c1b176bbe2d77b66f3..474532bc1767603340b62f88e3605d9859612833 100644 (file)
@@ -84,7 +84,9 @@ func stmts(nn *ir.Nodes) {
                        }
                }
 
-               stmts(n.PtrInit())
+               if len(n.Init()) != 0 {
+                       stmts(n.(ir.InitNode).PtrInit())
+               }
                switch n.Op() {
                case ir.OBLOCK:
                        n := n.(*ir.BlockStmt)
index 31b97a378703ee028a1e39b6a0efe5c5b2d13612..24fbe3dac031367eb753a0bca3e36543fee865a8 100644 (file)
@@ -639,7 +639,7 @@ func inlCallee(fn ir.Node) *ir.Func {
        return nil
 }
 
-func inlParam(t *types.Field, as ir.Node, inlvars map[*ir.Name]*ir.Name) ir.Node {
+func inlParam(t *types.Field, as ir.InitNode, inlvars map[*ir.Name]*ir.Name) ir.Node {
        if t.Nname == nil {
                return ir.BlankNode
        }
@@ -741,7 +741,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]b
                callee := n.X
                for callee.Op() == ir.OCONVNOP {
                        conv := callee.(*ir.ConvExpr)
-                       ninit.Append(conv.PtrInit().Take()...)
+                       ninit.Append(ir.TakeInit(conv)...)
                        callee = conv.X
                }
                if callee.Op() != ir.ONAME && callee.Op() != ir.OCLOSURE && callee.Op() != ir.OMETHEXPR {
index 92701326216e4f175e4c8602a16521aae7e68a35..93aa15abece25565cd547e5cb67141ddca386425 100644 (file)
@@ -80,13 +80,7 @@ func (n *miniNode) SetDiag(x bool) { n.bits.set(miniDiag, x) }
 
 // Empty, immutable graph structure.
 
-func (n *miniNode) Init() Nodes     { return Nodes{} }
-func (n *miniNode) PtrInit() *Nodes { return &immutableEmptyNodes }
-func (n *miniNode) SetInit(x Nodes) {
-       if x != nil {
-               panic(n.no("SetInit"))
-       }
-}
+func (n *miniNode) Init() Nodes { return Nodes{} }
 
 // Additional functionality unavailable.
 
index 9536503085bca1a6c304e04df206ffd575e8b146..9945cc987ac769cdf37ebf10dc8e387b865a9c60 100644 (file)
@@ -34,8 +34,6 @@ type Node interface {
        // Abstract graph structure, for generic traversals.
        Op() Op
        Init() Nodes
-       PtrInit() *Nodes
-       SetInit(x Nodes)
 
        // Fields specific to certain Ops only.
        Type() *types.Type
@@ -90,6 +88,20 @@ func MayBeShared(n Node) bool {
        return false
 }
 
+type InitNode interface {
+       Node
+       PtrInit() *Nodes
+       SetInit(x Nodes)
+}
+
+func TakeInit(n Node) Nodes {
+       init := n.Init()
+       if len(init) != 0 {
+               n.(InitNode).SetInit(nil)
+       }
+       return init
+}
+
 //go:generate stringer -type=Op -trimprefix=O node.go
 
 type Op uint8
@@ -311,35 +323,15 @@ const (
 // a slice to save space.
 type Nodes []Node
 
-// immutableEmptyNodes is an immutable, empty Nodes list.
-// The methods that would modify it panic instead.
-var immutableEmptyNodes = Nodes{}
-
-func (n *Nodes) mutate() {
-       if n == &immutableEmptyNodes {
-               panic("immutable Nodes.Set")
-       }
-}
-
 // Set sets n to a slice.
 // This takes ownership of the slice.
-func (n *Nodes) Set(s []Node) {
-       if n == &immutableEmptyNodes {
-               if len(s) == 0 {
-                       // Allow immutableEmptyNodes.Set(nil) (a no-op).
-                       return
-               }
-               n.mutate()
-       }
-       *n = s
-}
+func (n *Nodes) Set(s []Node) { *n = s }
 
 // Append appends entries to Nodes.
 func (n *Nodes) Append(a ...Node) {
        if len(a) == 0 {
                return
        }
-       n.mutate()
        *n = append(*n, a...)
 }
 
@@ -349,7 +341,6 @@ func (n *Nodes) Prepend(a ...Node) {
        if len(a) == 0 {
                return
        }
-       n.mutate()
        *n = append(a, *n...)
 }
 
@@ -544,15 +535,16 @@ func SetPos(n Node) src.XPos {
 
 // The result of InitExpr MUST be assigned back to n, e.g.
 //     n.Left = InitExpr(init, n.Left)
-func InitExpr(init []Node, n Node) Node {
+func InitExpr(init []Node, expr Node) Node {
        if len(init) == 0 {
-               return n
+               return expr
        }
-       if MayBeShared(n) {
+
+       n, ok := expr.(InitNode)
+       if !ok || MayBeShared(n) {
                // Introduce OCONVNOP to hold init list.
-               old := n
-               n = NewConvExpr(base.Pos, OCONVNOP, nil, old)
-               n.SetType(old.Type())
+               n = NewConvExpr(base.Pos, OCONVNOP, nil, expr)
+               n.SetType(expr.Type())
                n.SetTypecheck(1)
        }
 
index cc8a1c7c89a4f9faff4b5250d00786f6fa107567..948833f46e91d921184861e9a0266badc32ce6ce 100644 (file)
@@ -1200,7 +1200,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
        panic("unhandled Stmt")
 }
 
-func (p *noder) assignList(expr syntax.Expr, defn ir.Node, colas bool) []ir.Node {
+func (p *noder) assignList(expr syntax.Expr, defn ir.InitNode, colas bool) []ir.Node {
        if !colas {
                return p.exprList(expr)
        }
index 0822a4624ca0c5500f24ed9559f8da615e8d0076..0ee66df2cfc5b0cf603c7aa67463600ec2cbdf16 100644 (file)
@@ -914,7 +914,7 @@ func typecheck1(n ir.Node, top int) ir.Node {
        // Each must execute its own return n.
 }
 
-func typecheckargs(n ir.Node) {
+func typecheckargs(n ir.InitNode) {
        var list []ir.Node
        switch n := n.(type) {
        default:
index c01079d236bc03b0626bfe7c17971738ae1f9d2e..762baa0dd940d649e8e2c8e7d2476360fc680f19 100644 (file)
@@ -17,7 +17,7 @@ import (
 
 // walkAssign walks an OAS (AssignExpr) or OASOP (AssignOpExpr) node.
 func walkAssign(init *ir.Nodes, n ir.Node) ir.Node {
-       init.Append(n.PtrInit().Take()...)
+       init.Append(ir.TakeInit(n)...)
 
        var left, right ir.Node
        switch n.Op() {
@@ -124,7 +124,7 @@ func walkAssignDotType(n *ir.AssignListStmt, init *ir.Nodes) ir.Node {
 
 // walkAssignFunc walks an OAS2FUNC node.
 func walkAssignFunc(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
-       init.Append(n.PtrInit().Take()...)
+       init.Append(ir.TakeInit(n)...)
 
        r := n.Rhs[0]
        walkExprListSafe(n.Lhs, init)
@@ -142,7 +142,7 @@ func walkAssignFunc(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
 
 // walkAssignList walks an OAS2 node.
 func walkAssignList(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
-       init.Append(n.PtrInit().Take()...)
+       init.Append(ir.TakeInit(n)...)
        walkExprListSafe(n.Lhs, init)
        walkExprListSafe(n.Rhs, init)
        return ir.NewBlockStmt(src.NoXPos, ascompatee(ir.OAS, n.Lhs, n.Rhs, init))
@@ -150,7 +150,7 @@ func walkAssignList(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
 
 // walkAssignMapRead walks an OAS2MAPR node.
 func walkAssignMapRead(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
-       init.Append(n.PtrInit().Take()...)
+       init.Append(ir.TakeInit(n)...)
 
        r := n.Rhs[0].(*ir.IndexExpr)
        walkExprListSafe(n.Lhs, init)
@@ -213,7 +213,7 @@ func walkAssignMapRead(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
 
 // walkAssignRecv walks an OAS2RECV node.
 func walkAssignRecv(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
-       init.Append(n.PtrInit().Take()...)
+       init.Append(ir.TakeInit(n)...)
 
        r := n.Rhs[0].(*ir.UnaryExpr) // recv
        walkExprListSafe(n.Lhs, init)
index fe6045cbbd1d945cf40bcaf3319985b5dfdb7266..13837eeffc4ba5f691fb7dbb02c7155da482fcc3 100644 (file)
@@ -206,7 +206,7 @@ func walkCopy(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
 
 // walkDelete walks an ODELETE node.
 func walkDelete(init *ir.Nodes, n *ir.CallExpr) ir.Node {
-       init.Append(n.PtrInit().Take()...)
+       init.Append(ir.TakeInit(n)...)
        map_ := n.Args[0]
        key := n.Args[1]
        map_ = walkExpr(map_, init)
index 1fd09b42af4ca4e1d0911fa2d090c7d03ab3590d..7dfac300946bded62cf51de96d0f0e97b4bac025 100644 (file)
@@ -26,7 +26,7 @@ func walkExpr(n ir.Node, init *ir.Nodes) ir.Node {
                return n
        }
 
-       if init == n.PtrInit() {
+       if n, ok := n.(ir.InitNode); ok && init == n.PtrInit() {
                // not okay to use n->ninit when walking n,
                // because we might replace n with some other node
                // and would lose the init list.
@@ -35,7 +35,7 @@ func walkExpr(n ir.Node, init *ir.Nodes) ir.Node {
 
        if len(n.Init()) != 0 {
                walkStmtList(n.Init())
-               init.Append(n.PtrInit().Take()...)
+               init.Append(ir.TakeInit(n)...)
        }
 
        lno := ir.SetPos(n)
@@ -359,7 +359,7 @@ func safeExpr(n ir.Node, init *ir.Nodes) ir.Node {
 
        if len(n.Init()) != 0 {
                walkStmtList(n.Init())
-               init.Append(n.PtrInit().Take()...)
+               init.Append(ir.TakeInit(n)...)
        }
 
        switch n.Op() {
index e40c877ea939c12ef424b89ad70a5a19e9a1e680..679b795270e85e24ce645e4c903690fec7cb53f8 100644 (file)
@@ -466,8 +466,7 @@ func (o *orderState) init(n ir.Node) {
                }
                return
        }
-       o.stmtList(n.Init())
-       n.PtrInit().Set(nil)
+       o.stmtList(ir.TakeInit(n))
 }
 
 // call orders the call expression n.
@@ -938,8 +937,7 @@ func (o *orderState) stmt(n ir.Node) {
                                if !ir.IsAutoTmp(recv.X) {
                                        recv.X = o.copyExpr(recv.X)
                                }
-                               init := *r.PtrInit()
-                               r.PtrInit().Set(nil)
+                               init := ir.TakeInit(r)
 
                                colas := r.Def
                                do := func(i int, t *types.Type) {
@@ -1000,8 +998,7 @@ func (o *orderState) stmt(n ir.Node) {
 
                        // TODO(mdempsky): Is this actually necessary?
                        // walkselect appears to walk Ninit.
-                       cas.Body.Prepend(cas.Init()...)
-                       cas.PtrInit().Set(nil)
+                       cas.Body.Prepend(ir.TakeInit(cas)...)
                }
 
                o.out = append(o.out, n)
index 49a69e97513f27a24d15825a06d90e000711458f..3092b71d7294d8bc2dc96552202885c83906924e 100644 (file)
@@ -210,7 +210,7 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
                a.SetTypecheck(1)
                a.Lhs = []ir.Node{hv1, hb}
                a.Rhs = []ir.Node{ir.NewUnaryExpr(base.Pos, ir.ORECV, ha)}
-               *nfor.Cond.PtrInit() = []ir.Node{a}
+               nfor.Cond = ir.InitExpr([]ir.Node{a}, nfor.Cond)
                if v1 == nil {
                        body = nil
                } else {
index 1c5e1d7e64ac78438a0ce5ec357e6a48d77a0e47..c6e9b71384d501046c37487923a31e74c24b91f8 100644 (file)
@@ -17,8 +17,7 @@ func walkSelect(sel *ir.SelectStmt) {
                base.Fatalf("double walkselect")
        }
 
-       init := sel.Init()
-       sel.PtrInit().Set(nil)
+       init := ir.TakeInit(sel)
 
        init = append(init, walkSelectCases(sel.Cases)...)
        sel.Cases = nil
@@ -45,8 +44,7 @@ func walkSelectCases(cases []*ir.CommClause) []ir.Node {
                l := cas.Init()
                if cas.Comm != nil { // not default:
                        n := cas.Comm
-                       l = append(l, n.Init()...)
-                       n.PtrInit().Set(nil)
+                       l = append(l, ir.TakeInit(n)...)
                        switch n.Op() {
                        default:
                                base.Fatalf("select %v", n.Op())
@@ -171,8 +169,7 @@ func walkSelectCases(cases []*ir.CommClause) []ir.Node {
        for _, cas := range cases {
                ir.SetPos(cas)
 
-               init = append(init, cas.Init()...)
-               cas.PtrInit().Set(nil)
+               init = append(init, ir.TakeInit(cas)...)
 
                n := cas.Comm
                if n == nil { // default:
index 8641a58e2e797f497988f4d0e27fb08791bc247c..3440c6650642ee87abb40e58b71861da279f3ee0 100644 (file)
@@ -55,8 +55,7 @@ func walkStmt(n ir.Node) ir.Node {
                if n.Typecheck() == 0 {
                        base.Fatalf("missing typecheck: %+v", n)
                }
-               init := n.Init()
-               n.PtrInit().Set(nil)
+               init := ir.TakeInit(n)
                n = walkExpr(n, &init)
                if n.Op() == ir.ONAME {
                        // copy rewrote to a statement list and a temp for the length.
@@ -67,7 +66,7 @@ func walkStmt(n ir.Node) ir.Node {
                if len(init) > 0 {
                        switch n.Op() {
                        case ir.OAS, ir.OAS2, ir.OBLOCK:
-                               n.PtrInit().Prepend(init...)
+                               n.(ir.InitNode).PtrInit().Prepend(init...)
 
                        default:
                                init.Append(n)
@@ -191,9 +190,8 @@ func walkDecl(n *ir.Decl) ir.Node {
 // walkFor walks an OFOR or OFORUNTIL node.
 func walkFor(n *ir.ForStmt) ir.Node {
        if n.Cond != nil {
-               walkStmtList(n.Cond.Init())
-               init := n.Cond.Init()
-               n.Cond.PtrInit().Set(nil)
+               init := ir.TakeInit(n.Cond)
+               walkStmtList(init)
                n.Cond = walkExpr(n.Cond, &init)
                n.Cond = ir.InitExpr(init, n.Cond)
        }
@@ -257,7 +255,7 @@ func walkIf(n *ir.IfStmt) ir.Node {
 func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
        if len(n.Init()) != 0 {
                walkStmtList(n.Init())
-               init.Append(n.PtrInit().Take()...)
+               init.Append(ir.TakeInit(n)...)
        }
 
        isBuiltinCall := n.Op() != ir.OCALLFUNC && n.Op() != ir.OCALLMETH && n.Op() != ir.OCALLINTER
index 25f53a8e7c50c1cc63dac8aefa75fd063d6a92d4..57c2d43753b5eeb7c1c2530b42fa7a1b5751116c 100644 (file)
@@ -81,8 +81,7 @@ func walkRecv(n *ir.UnaryExpr) ir.Node {
        if n.Typecheck() == 0 {
                base.Fatalf("missing typecheck: %+v", n)
        }
-       init := n.Init()
-       n.PtrInit().Set(nil)
+       init := ir.TakeInit(n)
 
        n.X = walkExpr(n.X, &init)
        call := walkExpr(mkcall1(chanfn("chanrecv1", 2, n.X.Type()), nil, &init, n.X, typecheck.NodNil()), &init)