diff --git a/src/cmd/compile/internal/gc/inl.go b/src/cmd/compile/internal/gc/inl.go index 89c9873c1d..fd8e9cfd46 100644 --- a/src/cmd/compile/internal/gc/inl.go +++ b/src/cmd/compile/internal/gc/inl.go @@ -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) diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 7e8ae22e4e..f439237936 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -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: