mirror of
https://github.com/golang/go
synced 2024-11-19 12:34:47 -07:00
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: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
7a05fa8a70
commit
e6ea01685f
@ -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) {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
|||||||
|
|
||||||
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) {
|
|||||||
|
|
||||||
*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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
// 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 {
|
|||||||
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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user