Commit e6ea0168 authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/compile: remove global variables in inl.go

Change-Id: I06dedf4ebfa32b598f5545dc9354c8e4a95610b1
Reviewed-on: https://go-review.googlesource.com/20525
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 7a05fa8a
...@@ -32,17 +32,6 @@ import ( ...@@ -32,17 +32,6 @@ import (
"fmt" "fmt"
) )
// Used by caninl.
// Used by inlcalls
// Used during inlsubst[list]
var inlfn *Node // function currently being inlined
var inlretlabel *Node // target of the goto substituted in place of a return
var inlretvars []*Node // temp out variables
// Get the function's package. For ordinary functions it's on the ->sym, but for imported methods // Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
// the ->sym can be re-used in the local package, so peel it off the receiver's type. // the ->sym can be re-used in the local package, so peel it off the receiver's type.
func fnpkg(fn *Node) *Pkg { func fnpkg(fn *Node) *Pkg {
...@@ -553,9 +542,6 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -553,9 +542,6 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
fmt.Printf("%v: Before inlining: %v\n", n.Line(), Nconv(n, obj.FmtSign)) fmt.Printf("%v: Before inlining: %v\n", n.Line(), Nconv(n, obj.FmtSign))
} }
saveinlfn := inlfn
inlfn = fn
ninit := n.Ninit ninit := n.Ninit
//dumplist("ninit pre", ninit); //dumplist("ninit pre", ninit);
...@@ -569,7 +555,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -569,7 +555,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
dcl = fn.Func.Dcl dcl = fn.Func.Dcl
} }
inlretvars = nil var retvars []*Node
i := 0 i := 0
// Make temp names to use instead of the originals // Make temp names to use instead of the originals
...@@ -603,7 +589,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -603,7 +589,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
} }
ninit.Append(Nod(ODCL, m, nil)) ninit.Append(Nod(ODCL, m, nil))
inlretvars = append(inlretvars, m) retvars = append(retvars, m)
} }
// assign receiver. // assign receiver.
...@@ -774,18 +760,24 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -774,18 +760,24 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
} }
// zero the outparams // zero the outparams
for _, n := range inlretvars { for _, n := range retvars {
as = Nod(OAS, n, nil) as = Nod(OAS, n, nil)
typecheck(&as, Etop) typecheck(&as, Etop)
ninit.Append(as) ninit.Append(as)
} }
inlretlabel = newlabel_inl() retlabel := newlabel_inl()
inlgen++ inlgen++
body := inlsubstlist(fn.Func.Inl)
body = append(body, Nod(OGOTO, inlretlabel, nil)) // avoid 'not used' when function doesn't have return subst := inlsubst{
body = append(body, Nod(OLABEL, inlretlabel, nil)) retlabel: retlabel,
retvars: retvars,
}
body := subst.list(fn.Func.Inl)
body = append(body, Nod(OGOTO, retlabel, nil)) // avoid 'not used' when function doesn't have return
body = append(body, Nod(OLABEL, retlabel, nil))
typecheckslice(body, Etop) typecheckslice(body, Etop)
...@@ -795,7 +787,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -795,7 +787,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
call.Ninit.Set(ninit.Slice()) call.Ninit.Set(ninit.Slice())
call.Nbody.Set(body) call.Nbody.Set(body)
call.Rlist.Set(inlretvars) call.Rlist.Set(retvars)
call.Type = n.Type call.Type = n.Type
call.Typecheck = 1 call.Typecheck = 1
...@@ -812,8 +804,6 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) { ...@@ -812,8 +804,6 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
*np = call *np = call
inlfn = saveinlfn
// transitive inlining // transitive inlining
// might be nice to do this before exporting the body, // might be nice to do this before exporting the body,
// but can't emit the body with inlining expanded. // but can't emit the body with inlining expanded.
...@@ -893,19 +883,30 @@ func newlabel_inl() *Node { ...@@ -893,19 +883,30 @@ func newlabel_inl() *Node {
return n return n
} }
// inlsubst and inlsubstlist recursively copy the body of the saved // The inlsubst type implements the actual inlining of a single
// pristine ->inl body of the function while substituting references // function call.
// to input/output parameters with ones to the tmpnames, and type inlsubst struct {
// substituting returns with assignments to the output. // Target of the goto substituted in place of a return.
func inlsubstlist(ll Nodes) []*Node { retlabel *Node
// Temporary result variables.
retvars []*Node
}
// list inlines a list of nodes.
func (subst *inlsubst) list(ll Nodes) []*Node {
s := make([]*Node, 0, ll.Len()) s := make([]*Node, 0, ll.Len())
for _, n := range ll.Slice() { for _, n := range ll.Slice() {
s = append(s, inlsubst(n)) s = append(s, subst.node(n))
} }
return s return s
} }
func inlsubst(n *Node) *Node { // node recursively copies a node from the saved pristine body of the
// inlined function, substituting references to input/output
// parameters with ones to the tmpnames, and substituting returns with
// assignments to the output.
func (subst *inlsubst) node(n *Node) *Node {
if n == nil { if n == nil {
return nil return nil
} }
...@@ -931,18 +932,20 @@ func inlsubst(n *Node) *Node { ...@@ -931,18 +932,20 @@ func inlsubst(n *Node) *Node {
// dump("Return before substitution", n); // dump("Return before substitution", n);
case ORETURN: case ORETURN:
m := Nod(OGOTO, inlretlabel, nil) m := Nod(OGOTO, subst.retlabel, nil)
m.Ninit.Set(inlsubstlist(n.Ninit)) m.Ninit.Set(subst.list(n.Ninit))
if len(inlretvars) != 0 && n.List.Len() != 0 { if len(subst.retvars) != 0 && n.List.Len() != 0 {
as := Nod(OAS2, nil, nil) as := Nod(OAS2, nil, nil)
// shallow copy or OINLCALL->rlist will be the same list, and later walk and typecheck may clobber that. // Make a shallow copy of retvars.
for _, n := range inlretvars { // Otherwise OINLCALL.Rlist will be the same list,
// and later walk and typecheck may clobber it.
for _, n := range subst.retvars {
as.List.Append(n) as.List.Append(n)
} }
as.Rlist.Set(inlsubstlist(n.List)) as.Rlist.Set(subst.list(n.List))
typecheck(&as, Etop) typecheck(&as, Etop)
m.Ninit.Append(as) m.Ninit.Append(as)
} }
...@@ -971,12 +974,12 @@ func inlsubst(n *Node) *Node { ...@@ -971,12 +974,12 @@ func inlsubst(n *Node) *Node {
Fatalf("cannot inline function containing closure: %v", Nconv(n, obj.FmtSign)) Fatalf("cannot inline function containing closure: %v", Nconv(n, obj.FmtSign))
} }
m.Left = inlsubst(n.Left) m.Left = subst.node(n.Left)
m.Right = inlsubst(n.Right) m.Right = subst.node(n.Right)
m.List.Set(inlsubstlist(n.List)) m.List.Set(subst.list(n.List))
m.Rlist.Set(inlsubstlist(n.Rlist)) m.Rlist.Set(subst.list(n.Rlist))
m.Ninit.Set(append(m.Ninit.Slice(), inlsubstlist(n.Ninit)...)) m.Ninit.Set(append(m.Ninit.Slice(), subst.list(n.Ninit)...))
m.Nbody.Set(inlsubstlist(n.Nbody)) m.Nbody.Set(subst.list(n.Nbody))
return m return m
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment