1
0
mirror of https://github.com/golang/go synced 2024-11-27 00:01:23 -07:00

[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>
This commit is contained in:
Matthew Dempsky 2021-01-02 01:04:19 -08:00
parent 1544a03198
commit 2f2d4b4e68
14 changed files with 52 additions and 73 deletions

View 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() { switch n.Op() {
case ir.OBLOCK: case ir.OBLOCK:
n := n.(*ir.BlockStmt) n := n.(*ir.BlockStmt)

View File

@ -639,7 +639,7 @@ func inlCallee(fn ir.Node) *ir.Func {
return nil 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 { if t.Nname == nil {
return ir.BlankNode 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 callee := n.X
for callee.Op() == ir.OCONVNOP { for callee.Op() == ir.OCONVNOP {
conv := callee.(*ir.ConvExpr) conv := callee.(*ir.ConvExpr)
ninit.Append(conv.PtrInit().Take()...) ninit.Append(ir.TakeInit(conv)...)
callee = conv.X callee = conv.X
} }
if callee.Op() != ir.ONAME && callee.Op() != ir.OCLOSURE && callee.Op() != ir.OMETHEXPR { if callee.Op() != ir.ONAME && callee.Op() != ir.OCLOSURE && callee.Op() != ir.OMETHEXPR {

View File

@ -80,13 +80,7 @@ func (n *miniNode) SetDiag(x bool) { n.bits.set(miniDiag, x) }
// Empty, immutable graph structure. // Empty, immutable graph structure.
func (n *miniNode) Init() Nodes { return Nodes{} } 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"))
}
}
// Additional functionality unavailable. // Additional functionality unavailable.

View File

@ -34,8 +34,6 @@ type Node interface {
// Abstract graph structure, for generic traversals. // Abstract graph structure, for generic traversals.
Op() Op Op() Op
Init() Nodes Init() Nodes
PtrInit() *Nodes
SetInit(x Nodes)
// Fields specific to certain Ops only. // Fields specific to certain Ops only.
Type() *types.Type Type() *types.Type
@ -90,6 +88,20 @@ func MayBeShared(n Node) bool {
return false 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 //go:generate stringer -type=Op -trimprefix=O node.go
type Op uint8 type Op uint8
@ -311,35 +323,15 @@ const (
// a slice to save space. // a slice to save space.
type Nodes []Node 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. // Set sets n to a slice.
// This takes ownership of the slice. // This takes ownership of the slice.
func (n *Nodes) Set(s []Node) { func (n *Nodes) Set(s []Node) { *n = s }
if n == &immutableEmptyNodes {
if len(s) == 0 {
// Allow immutableEmptyNodes.Set(nil) (a no-op).
return
}
n.mutate()
}
*n = s
}
// Append appends entries to Nodes. // Append appends entries to Nodes.
func (n *Nodes) Append(a ...Node) { func (n *Nodes) Append(a ...Node) {
if len(a) == 0 { if len(a) == 0 {
return return
} }
n.mutate()
*n = append(*n, a...) *n = append(*n, a...)
} }
@ -349,7 +341,6 @@ func (n *Nodes) Prepend(a ...Node) {
if len(a) == 0 { if len(a) == 0 {
return return
} }
n.mutate()
*n = append(a, *n...) *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. // The result of InitExpr MUST be assigned back to n, e.g.
// n.Left = InitExpr(init, n.Left) // n.Left = InitExpr(init, n.Left)
func InitExpr(init []Node, n Node) Node { func InitExpr(init []Node, expr Node) Node {
if len(init) == 0 { 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. // Introduce OCONVNOP to hold init list.
old := n n = NewConvExpr(base.Pos, OCONVNOP, nil, expr)
n = NewConvExpr(base.Pos, OCONVNOP, nil, old) n.SetType(expr.Type())
n.SetType(old.Type())
n.SetTypecheck(1) n.SetTypecheck(1)
} }

View File

@ -1200,7 +1200,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
panic("unhandled Stmt") 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 { if !colas {
return p.exprList(expr) return p.exprList(expr)
} }

View File

@ -914,7 +914,7 @@ func typecheck1(n ir.Node, top int) ir.Node {
// Each must execute its own return n. // Each must execute its own return n.
} }
func typecheckargs(n ir.Node) { func typecheckargs(n ir.InitNode) {
var list []ir.Node var list []ir.Node
switch n := n.(type) { switch n := n.(type) {
default: default:

View File

@ -17,7 +17,7 @@ import (
// walkAssign walks an OAS (AssignExpr) or OASOP (AssignOpExpr) node. // walkAssign walks an OAS (AssignExpr) or OASOP (AssignOpExpr) node.
func walkAssign(init *ir.Nodes, n ir.Node) ir.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 var left, right ir.Node
switch n.Op() { switch n.Op() {
@ -124,7 +124,7 @@ func walkAssignDotType(n *ir.AssignListStmt, init *ir.Nodes) ir.Node {
// walkAssignFunc walks an OAS2FUNC node. // walkAssignFunc walks an OAS2FUNC node.
func walkAssignFunc(init *ir.Nodes, n *ir.AssignListStmt) ir.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] r := n.Rhs[0]
walkExprListSafe(n.Lhs, init) walkExprListSafe(n.Lhs, init)
@ -142,7 +142,7 @@ func walkAssignFunc(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
// walkAssignList walks an OAS2 node. // walkAssignList walks an OAS2 node.
func walkAssignList(init *ir.Nodes, n *ir.AssignListStmt) ir.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.Lhs, init)
walkExprListSafe(n.Rhs, init) walkExprListSafe(n.Rhs, init)
return ir.NewBlockStmt(src.NoXPos, ascompatee(ir.OAS, n.Lhs, 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. // walkAssignMapRead walks an OAS2MAPR node.
func walkAssignMapRead(init *ir.Nodes, n *ir.AssignListStmt) ir.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) r := n.Rhs[0].(*ir.IndexExpr)
walkExprListSafe(n.Lhs, init) walkExprListSafe(n.Lhs, init)
@ -213,7 +213,7 @@ func walkAssignMapRead(init *ir.Nodes, n *ir.AssignListStmt) ir.Node {
// walkAssignRecv walks an OAS2RECV node. // walkAssignRecv walks an OAS2RECV node.
func walkAssignRecv(init *ir.Nodes, n *ir.AssignListStmt) ir.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 r := n.Rhs[0].(*ir.UnaryExpr) // recv
walkExprListSafe(n.Lhs, init) walkExprListSafe(n.Lhs, init)

View File

@ -206,7 +206,7 @@ func walkCopy(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
// walkDelete walks an ODELETE node. // walkDelete walks an ODELETE node.
func walkDelete(init *ir.Nodes, n *ir.CallExpr) ir.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] map_ := n.Args[0]
key := n.Args[1] key := n.Args[1]
map_ = walkExpr(map_, init) map_ = walkExpr(map_, init)

View File

@ -26,7 +26,7 @@ func walkExpr(n ir.Node, init *ir.Nodes) ir.Node {
return n 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, // not okay to use n->ninit when walking n,
// because we might replace n with some other node // because we might replace n with some other node
// and would lose the init list. // 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 { if len(n.Init()) != 0 {
walkStmtList(n.Init()) walkStmtList(n.Init())
init.Append(n.PtrInit().Take()...) init.Append(ir.TakeInit(n)...)
} }
lno := ir.SetPos(n) lno := ir.SetPos(n)
@ -359,7 +359,7 @@ func safeExpr(n ir.Node, init *ir.Nodes) ir.Node {
if len(n.Init()) != 0 { if len(n.Init()) != 0 {
walkStmtList(n.Init()) walkStmtList(n.Init())
init.Append(n.PtrInit().Take()...) init.Append(ir.TakeInit(n)...)
} }
switch n.Op() { switch n.Op() {

View File

@ -466,8 +466,7 @@ func (o *orderState) init(n ir.Node) {
} }
return return
} }
o.stmtList(n.Init()) o.stmtList(ir.TakeInit(n))
n.PtrInit().Set(nil)
} }
// call orders the call expression n. // call orders the call expression n.
@ -938,8 +937,7 @@ func (o *orderState) stmt(n ir.Node) {
if !ir.IsAutoTmp(recv.X) { if !ir.IsAutoTmp(recv.X) {
recv.X = o.copyExpr(recv.X) recv.X = o.copyExpr(recv.X)
} }
init := *r.PtrInit() init := ir.TakeInit(r)
r.PtrInit().Set(nil)
colas := r.Def colas := r.Def
do := func(i int, t *types.Type) { do := func(i int, t *types.Type) {
@ -1000,8 +998,7 @@ func (o *orderState) stmt(n ir.Node) {
// TODO(mdempsky): Is this actually necessary? // TODO(mdempsky): Is this actually necessary?
// walkselect appears to walk Ninit. // walkselect appears to walk Ninit.
cas.Body.Prepend(cas.Init()...) cas.Body.Prepend(ir.TakeInit(cas)...)
cas.PtrInit().Set(nil)
} }
o.out = append(o.out, n) o.out = append(o.out, n)

View File

@ -210,7 +210,7 @@ func walkRange(nrange *ir.RangeStmt) ir.Node {
a.SetTypecheck(1) a.SetTypecheck(1)
a.Lhs = []ir.Node{hv1, hb} a.Lhs = []ir.Node{hv1, hb}
a.Rhs = []ir.Node{ir.NewUnaryExpr(base.Pos, ir.ORECV, ha)} 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 { if v1 == nil {
body = nil body = nil
} else { } else {

View File

@ -17,8 +17,7 @@ func walkSelect(sel *ir.SelectStmt) {
base.Fatalf("double walkselect") base.Fatalf("double walkselect")
} }
init := sel.Init() init := ir.TakeInit(sel)
sel.PtrInit().Set(nil)
init = append(init, walkSelectCases(sel.Cases)...) init = append(init, walkSelectCases(sel.Cases)...)
sel.Cases = nil sel.Cases = nil
@ -45,8 +44,7 @@ func walkSelectCases(cases []*ir.CommClause) []ir.Node {
l := cas.Init() l := cas.Init()
if cas.Comm != nil { // not default: if cas.Comm != nil { // not default:
n := cas.Comm n := cas.Comm
l = append(l, n.Init()...) l = append(l, ir.TakeInit(n)...)
n.PtrInit().Set(nil)
switch n.Op() { switch n.Op() {
default: default:
base.Fatalf("select %v", n.Op()) base.Fatalf("select %v", n.Op())
@ -171,8 +169,7 @@ func walkSelectCases(cases []*ir.CommClause) []ir.Node {
for _, cas := range cases { for _, cas := range cases {
ir.SetPos(cas) ir.SetPos(cas)
init = append(init, cas.Init()...) init = append(init, ir.TakeInit(cas)...)
cas.PtrInit().Set(nil)
n := cas.Comm n := cas.Comm
if n == nil { // default: if n == nil { // default:

View File

@ -55,8 +55,7 @@ func walkStmt(n ir.Node) ir.Node {
if n.Typecheck() == 0 { if n.Typecheck() == 0 {
base.Fatalf("missing typecheck: %+v", n) base.Fatalf("missing typecheck: %+v", n)
} }
init := n.Init() init := ir.TakeInit(n)
n.PtrInit().Set(nil)
n = walkExpr(n, &init) n = walkExpr(n, &init)
if n.Op() == ir.ONAME { if n.Op() == ir.ONAME {
// copy rewrote to a statement list and a temp for the length. // 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 { if len(init) > 0 {
switch n.Op() { switch n.Op() {
case ir.OAS, ir.OAS2, ir.OBLOCK: case ir.OAS, ir.OAS2, ir.OBLOCK:
n.PtrInit().Prepend(init...) n.(ir.InitNode).PtrInit().Prepend(init...)
default: default:
init.Append(n) init.Append(n)
@ -191,9 +190,8 @@ func walkDecl(n *ir.Decl) ir.Node {
// walkFor walks an OFOR or OFORUNTIL node. // walkFor walks an OFOR or OFORUNTIL node.
func walkFor(n *ir.ForStmt) ir.Node { func walkFor(n *ir.ForStmt) ir.Node {
if n.Cond != nil { if n.Cond != nil {
walkStmtList(n.Cond.Init()) init := ir.TakeInit(n.Cond)
init := n.Cond.Init() walkStmtList(init)
n.Cond.PtrInit().Set(nil)
n.Cond = walkExpr(n.Cond, &init) n.Cond = walkExpr(n.Cond, &init)
n.Cond = ir.InitExpr(init, n.Cond) 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 { func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
if len(n.Init()) != 0 { if len(n.Init()) != 0 {
walkStmtList(n.Init()) 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 isBuiltinCall := n.Op() != ir.OCALLFUNC && n.Op() != ir.OCALLMETH && n.Op() != ir.OCALLINTER

View File

@ -81,8 +81,7 @@ func walkRecv(n *ir.UnaryExpr) ir.Node {
if n.Typecheck() == 0 { if n.Typecheck() == 0 {
base.Fatalf("missing typecheck: %+v", n) base.Fatalf("missing typecheck: %+v", n)
} }
init := n.Init() init := ir.TakeInit(n)
n.PtrInit().Set(nil)
n.X = walkExpr(n.X, &init) n.X = walkExpr(n.X, &init)
call := walkExpr(mkcall1(chanfn("chanrecv1", 2, n.X.Type()), nil, &init, n.X, typecheck.NodNil()), &init) call := walkExpr(mkcall1(chanfn("chanrecv1", 2, n.X.Type()), nil, &init, n.X, typecheck.NodNil()), &init)