aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-01-02 01:04:19 -0800
committerMatthew Dempsky <mdempsky@google.com>2021-01-02 10:57:23 +0000
commit2f2d4b4e68ab2fc448a1c2daf793b11ccde2fb16 (patch)
tree1c95a61ad6bbed6518f99f84e1e0cf77dce57f10
parent1544a03198139656ef4ebc287f2287ad19c19a51 (diff)
downloadgo-2f2d4b4e68ab2fc448a1c2daf793b11ccde2fb16.tar.gz
go-2f2d4b4e68ab2fc448a1c2daf793b11ccde2fb16.zip
[dev.regabi] cmd/compile: remove {Ptr,Set}Init from Node interface
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>
-rw-r--r--src/cmd/compile/internal/deadcode/deadcode.go4
-rw-r--r--src/cmd/compile/internal/inline/inl.go4
-rw-r--r--src/cmd/compile/internal/ir/mini.go8
-rw-r--r--src/cmd/compile/internal/ir/node.go52
-rw-r--r--src/cmd/compile/internal/noder/noder.go2
-rw-r--r--src/cmd/compile/internal/typecheck/typecheck.go2
-rw-r--r--src/cmd/compile/internal/walk/assign.go10
-rw-r--r--src/cmd/compile/internal/walk/builtin.go2
-rw-r--r--src/cmd/compile/internal/walk/expr.go6
-rw-r--r--src/cmd/compile/internal/walk/order.go9
-rw-r--r--src/cmd/compile/internal/walk/range.go2
-rw-r--r--src/cmd/compile/internal/walk/select.go9
-rw-r--r--src/cmd/compile/internal/walk/stmt.go12
-rw-r--r--src/cmd/compile/internal/walk/walk.go3
14 files changed, 52 insertions, 73 deletions
diff --git a/src/cmd/compile/internal/deadcode/deadcode.go b/src/cmd/compile/internal/deadcode/deadcode.go
index 5453cfe396..474532bc17 100644
--- a/src/cmd/compile/internal/deadcode/deadcode.go
+++ b/src/cmd/compile/internal/deadcode/deadcode.go
@@ -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)
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
index 31b97a3787..24fbe3dac0 100644
--- a/src/cmd/compile/internal/inline/inl.go
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -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 {
diff --git a/src/cmd/compile/internal/ir/mini.go b/src/cmd/compile/internal/ir/mini.go
index 9270132621..93aa15abec 100644
--- a/src/cmd/compile/internal/ir/mini.go
+++ b/src/cmd/compile/internal/ir/mini.go
@@ -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.
diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go
index 9536503085..9945cc987a 100644
--- a/src/cmd/compile/internal/ir/node.go
+++ b/src/cmd/compile/internal/ir/node.go
@@ -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)
}
diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go
index cc8a1c7c89..948833f46e 100644
--- a/src/cmd/compile/internal/noder/noder.go
+++ b/src/cmd/compile/internal/noder/noder.go
@@ -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)
}
diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go
index 0822a4624c..0ee66df2cf 100644
--- a/src/cmd/compile/internal/typecheck/typecheck.go
+++ b/src/cmd/compile/internal/typecheck/typecheck.go
@@ -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:
diff --git a/src/cmd/compile/internal/walk/assign.go b/src/cmd/compile/internal/walk/assign.go
index c01079d236..762baa0dd9 100644
--- a/src/cmd/compile/internal/walk/assign.go
+++ b/src/cmd/compile/internal/walk/assign.go
@@ -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)
diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go
index fe6045cbbd..13837eeffc 100644
--- a/src/cmd/compile/internal/walk/builtin.go
+++ b/src/cmd/compile/internal/walk/builtin.go
@@ -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)
diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go
index 1fd09b42af..7dfac30094 100644
--- a/src/cmd/compile/internal/walk/expr.go
+++ b/src/cmd/compile/internal/walk/expr.go
@@ -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() {
diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go
index e40c877ea9..679b795270 100644
--- a/src/cmd/compile/internal/walk/order.go
+++ b/src/cmd/compile/internal/walk/order.go
@@ -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)
diff --git a/src/cmd/compile/internal/walk/range.go b/src/cmd/compile/internal/walk/range.go
index 49a69e9751..3092b71d72 100644
--- a/src/cmd/compile/internal/walk/range.go
+++ b/src/cmd/compile/internal/walk/range.go
@@ -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 {
diff --git a/src/cmd/compile/internal/walk/select.go b/src/cmd/compile/internal/walk/select.go
index 1c5e1d7e64..c6e9b71384 100644
--- a/src/cmd/compile/internal/walk/select.go
+++ b/src/cmd/compile/internal/walk/select.go
@@ -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:
diff --git a/src/cmd/compile/internal/walk/stmt.go b/src/cmd/compile/internal/walk/stmt.go
index 8641a58e2e..3440c66506 100644
--- a/src/cmd/compile/internal/walk/stmt.go
+++ b/src/cmd/compile/internal/walk/stmt.go
@@ -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
diff --git a/src/cmd/compile/internal/walk/walk.go b/src/cmd/compile/internal/walk/walk.go
index 25f53a8e7c..57c2d43753 100644
--- a/src/cmd/compile/internal/walk/walk.go
+++ b/src/cmd/compile/internal/walk/walk.go
@@ -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)