aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)