]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove global variables in inl.go
authorIan Lance Taylor <iant@golang.org>
Thu, 10 Mar 2016 19:49:20 +0000 (11:49 -0800)
committerIan Lance Taylor <iant@golang.org>
Thu, 10 Mar 2016 22:49:53 +0000 (22:49 +0000)
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: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/inl.go

index 35df490600f85492422aad5fd9c526ba7a929a8b..a2fee2a97e3f49d0d1217f5d0037b8da44ed3d40 100644 (file)
@@ -32,17 +32,6 @@ import (
        "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
 // the ->sym can be re-used in the local package, so peel it off the receiver's type.
 func fnpkg(fn *Node) *Pkg {
@@ -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))
        }
 
-       saveinlfn := inlfn
-       inlfn = fn
-
        ninit := n.Ninit
 
        //dumplist("ninit pre", ninit);
@@ -569,7 +555,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
                dcl = fn.Func.Dcl
        }
 
-       inlretvars = nil
+       var retvars []*Node
        i := 0
 
        // Make temp names to use instead of the originals
@@ -603,7 +589,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
                }
 
                ninit.Append(Nod(ODCL, m, nil))
-               inlretvars = append(inlretvars, m)
+               retvars = append(retvars, m)
        }
 
        // assign receiver.
@@ -774,18 +760,24 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
        }
 
        // zero the outparams
-       for _, n := range inlretvars {
+       for _, n := range retvars {
                as = Nod(OAS, n, nil)
                typecheck(&as, Etop)
                ninit.Append(as)
        }
 
-       inlretlabel = newlabel_inl()
+       retlabel := newlabel_inl()
        inlgen++
-       body := inlsubstlist(fn.Func.Inl)
 
-       body = append(body, Nod(OGOTO, inlretlabel, nil)) // avoid 'not used' when function doesn't have return
-       body = append(body, Nod(OLABEL, inlretlabel, nil))
+       subst := inlsubst{
+               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)
 
@@ -795,7 +787,7 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
 
        call.Ninit.Set(ninit.Slice())
        call.Nbody.Set(body)
-       call.Rlist.Set(inlretvars)
+       call.Rlist.Set(retvars)
        call.Type = n.Type
        call.Typecheck = 1
 
@@ -812,8 +804,6 @@ func mkinlcall1(np **Node, fn *Node, isddd bool) {
 
        *np = call
 
-       inlfn = saveinlfn
-
        // transitive inlining
        // might be nice to do this before exporting the body,
        // but can't emit the body with inlining expanded.
@@ -893,19 +883,30 @@ func newlabel_inl() *Node {
        return n
 }
 
-// inlsubst and inlsubstlist recursively copy the body of the saved
-// pristine ->inl body of the function while substituting references
-// to input/output parameters with ones to the tmpnames, and
-// substituting returns with assignments to the output.
-func inlsubstlist(ll Nodes) []*Node {
+// The inlsubst type implements the actual inlining of a single
+// function call.
+type inlsubst struct {
+       // Target of the goto substituted in place of a return.
+       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())
        for _, n := range ll.Slice() {
-               s = append(s, inlsubst(n))
+               s = append(s, subst.node(n))
        }
        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 {
                return nil
        }
@@ -931,18 +932,20 @@ func inlsubst(n *Node) *Node {
 
        //              dump("Return before substitution", n);
        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)
 
-                       // shallow copy or OINLCALL->rlist will be the same list, and later walk and typecheck may clobber that.
-                       for _, n := range inlretvars {
+                       // Make a shallow copy of retvars.
+                       // 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.Rlist.Set(inlsubstlist(n.List))
+                       as.Rlist.Set(subst.list(n.List))
                        typecheck(&as, Etop)
                        m.Ninit.Append(as)
                }
@@ -971,12 +974,12 @@ func inlsubst(n *Node) *Node {
                Fatalf("cannot inline function containing closure: %v", Nconv(n, obj.FmtSign))
        }
 
-       m.Left = inlsubst(n.Left)
-       m.Right = inlsubst(n.Right)
-       m.List.Set(inlsubstlist(n.List))
-       m.Rlist.Set(inlsubstlist(n.Rlist))
-       m.Ninit.Set(append(m.Ninit.Slice(), inlsubstlist(n.Ninit)...))
-       m.Nbody.Set(inlsubstlist(n.Nbody))
+       m.Left = subst.node(n.Left)
+       m.Right = subst.node(n.Right)
+       m.List.Set(subst.list(n.List))
+       m.Rlist.Set(subst.list(n.Rlist))
+       m.Ninit.Set(append(m.Ninit.Slice(), subst.list(n.Ninit)...))
+       m.Nbody.Set(subst.list(n.Nbody))
 
        return m
 }