[dev.regabi] cmd/compile: use explicit block statements for init

For statements like goto that don't need an init, use an
explicit block statement instead of forcing them to have one.

There is also one call to addinit that is being replaced with
a block. That call is the source of much of my confusion
regarding init statements: walkstmt calls addinit on a statement,
whereas all the other uses of addinit are on expressions.

After this CL, they're all expressions.

Passes buildall w/ toolstash -cmp.

Change-Id: Ifdef9d318c236dc1a7567f9e9ef4a6bedd3fe81f
Reviewed-on: https://go-review.googlesource.com/c/go/+/274597
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Russ Cox 2020-11-30 23:49:25 -05:00
parent ecc8d15bc5
commit 64bc656aed
2 changed files with 33 additions and 24 deletions

View File

@ -527,8 +527,8 @@ func inlcalls(fn *ir.Func) {
// Turn an OINLCALL into a statement.
func inlconv2stmt(inlcall ir.Node) ir.Node {
n := ir.NodAt(inlcall.Pos(), ir.OBLOCK, nil, nil)
n.SetList(inlcall.Body())
n.SetInit(inlcall.Init())
n.SetList(inlcall.Init())
n.PtrList().AppendNodes(inlcall.PtrBody())
return n
}
@ -543,7 +543,7 @@ func inlconv2expr(n ir.Node) ir.Node {
// Turn the rlist (with the return values) of the OINLCALL in
// n into an expression list lumping the ninit and body
// containing the inlined statements on the first list element so
// order will be preserved Used in return, oas2func and call
// order will be preserved. Used in return, oas2func and call
// statements.
func inlconv2list(n ir.Node) []ir.Node {
if n.Op() != ir.OINLCALL || n.Rlist().Len() == 0 {
@ -1330,9 +1330,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
// dump("Return before substitution", n);
case ir.ORETURN:
m := nodSym(ir.OGOTO, nil, subst.retlabel)
m.PtrInit().Set(subst.list(n.Init()))
init := subst.list(n.Init())
if len(subst.retvars) != 0 && n.List().Len() != 0 {
as := ir.Nod(ir.OAS2, nil, nil)
@ -1352,14 +1350,11 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
}
as = typecheck(as, ctxStmt)
m.PtrInit().Append(as)
init = append(init, as)
}
typecheckslice(m.Init().Slice(), ctxStmt)
m = typecheck(m, ctxStmt)
// dump("Return after substitution", m);
return m
init = append(init, nodSym(ir.OGOTO, nil, subst.retlabel))
typecheckslice(init, ctxStmt)
return ir.NewBlockStmt(base.Pos, init)
case ir.OGOTO, ir.OLABEL:
m := ir.Copy(n)

View File

@ -147,16 +147,25 @@ func walkstmt(n ir.Node) ir.Node {
if n.Typecheck() == 0 {
base.Fatalf("missing typecheck: %+v", n)
}
wascopy := n.Op() == ir.OCOPY
init := n.Init()
n.PtrInit().Set(nil)
n = walkexpr(n, &init)
if wascopy && n.Op() == ir.ONAME {
if n.Op() == ir.ONAME {
// copy rewrote to a statement list and a temp for the length.
// Throw away the temp to avoid plain values as statements.
n = ir.NodAt(n.Pos(), ir.OBLOCK, nil, nil)
n = ir.NewBlockStmt(n.Pos(), init.Slice())
init.Set(nil)
}
if init.Len() > 0 {
switch n.Op() {
case ir.OAS, ir.OAS2, ir.OBLOCK:
n.PtrInit().Prepend(init.Slice()...)
default:
init.Append(n)
n = ir.NewBlockStmt(n.Pos(), init.Slice())
}
}
n = addinit(n, init.Slice())
// special case for a receive where we throw away
// the value received.
@ -223,29 +232,34 @@ func walkstmt(n ir.Node) ir.Node {
}
fallthrough
case ir.OGO:
var init ir.Nodes
switch n.Left().Op() {
case ir.OPRINT, ir.OPRINTN:
n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
n.SetLeft(wrapCall(n.Left(), &init))
case ir.ODELETE:
if mapfast(n.Left().List().First().Type()) == mapslow {
n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
n.SetLeft(wrapCall(n.Left(), &init))
} else {
n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
n.SetLeft(walkexpr(n.Left(), &init))
}
case ir.OCOPY:
n.SetLeft(copyany(n.Left(), n.PtrInit(), true))
n.SetLeft(copyany(n.Left(), &init, true))
case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
if n.Left().Body().Len() > 0 {
n.SetLeft(wrapCall(n.Left(), n.PtrInit()))
n.SetLeft(wrapCall(n.Left(), &init))
} else {
n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
n.SetLeft(walkexpr(n.Left(), &init))
}
default:
n.SetLeft(walkexpr(n.Left(), n.PtrInit()))
n.SetLeft(walkexpr(n.Left(), &init))
}
if init.Len() > 0 {
init.Append(n)
n = ir.NewBlockStmt(n.Pos(), init.Slice())
}
case ir.OFOR, ir.OFORUNTIL: