Commit 22452ac5 authored by Dave Cheney's avatar Dave Cheney

cmd/compile: use []*Node instead of NodeList in bottomUpVisitor

This one of a set of changes to make the transition away from NodeList
easier by removing cases in which NodeList doesn't act semi-trivially like a
[]*Node.

This CL was originally prepared by Josh Bleecher Snyder <josharian@gmail.com>.

This change passes go build -toolexec 'toolstash -cmp' -a std.

Change-Id: I582ff8b077eb384b84721a1edb0c1efbc0c40059
Reviewed-on: https://go-review.googlesource.com/14304Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarDave Cheney <dave@cheney.net>
Run-TryBot: Dave Cheney <dave@cheney.net>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 5a3ff6c8
......@@ -34,10 +34,10 @@ import (
// when analyzing a set of mutually recursive functions.
type bottomUpVisitor struct {
analyze func(*NodeList, bool)
analyze func([]*Node, bool)
visitgen uint32
nodeID map[*Node]uint32
stack *NodeList
stack []*Node
}
// visitBottomUp invokes analyze on the ODCLFUNC nodes listed in list.
......@@ -53,7 +53,7 @@ type bottomUpVisitor struct {
// If recursive is false, the list consists of only a single function and its closures.
// If recursive is true, the list may still contain only a single function,
// if that function is itself recursive.
func visitBottomUp(list *NodeList, analyze func(list *NodeList, recursive bool)) {
func visitBottomUp(list *NodeList, analyze func(list []*Node, recursive bool)) {
var v bottomUpVisitor
v.analyze = analyze
v.nodeID = make(map[*Node]uint32)
......@@ -76,10 +76,7 @@ func (v *bottomUpVisitor) visit(n *Node) uint32 {
v.visitgen++
min := v.visitgen
l := new(NodeList)
l.Next = v.stack
l.N = n
v.stack = l
v.stack = append(v.stack, n)
min = v.visitcodelist(n.Nbody, min)
if (min == id || min == id+1) && n.Func.FCurfn == nil {
// This node is the root of a strongly connected component.
......@@ -93,17 +90,19 @@ func (v *bottomUpVisitor) visit(n *Node) uint32 {
// Remove connected component from stack.
// Mark walkgen so that future visits return a large number
// so as not to affect the caller's min.
block := v.stack
var l *NodeList
for l = v.stack; l.N != n; l = l.Next {
v.nodeID[l.N] = ^uint32(0)
var i int
for i = len(v.stack) - 1; i >= 0; i-- {
x := v.stack[i]
if x == n {
break
}
v.nodeID[x] = ^uint32(0)
}
v.nodeID[n] = ^uint32(0)
v.stack = l.Next
l.Next = nil
block := v.stack[i:]
// Run escape analysis on this set of functions.
v.stack = v.stack[:i]
v.analyze(block, recursive)
}
......@@ -425,7 +424,7 @@ func (e *EscState) curfnSym(n *Node) *Sym {
return funcSym(nE.Curfn)
}
func escAnalyze(all *NodeList, recursive bool) {
func escAnalyze(all []*Node, recursive bool) {
var es EscState
e := &es
e.theSink.Op = ONAME
......@@ -435,16 +434,16 @@ func escAnalyze(all *NodeList, recursive bool) {
e.nodeEscState(&e.theSink).Escloopdepth = -1
e.recursive = recursive
for l := all; l != nil; l = l.Next {
if l.N.Op == ODCLFUNC {
l.N.Esc = EscFuncPlanned
for i := len(all) - 1; i >= 0; i-- {
if n := all[i]; n.Op == ODCLFUNC {
n.Esc = EscFuncPlanned
}
}
// flow-analyze functions
for l := all; l != nil; l = l.Next {
if l.N.Op == ODCLFUNC {
escfunc(e, l.N)
for i := len(all) - 1; i >= 0; i-- {
if n := all[i]; n.Op == ODCLFUNC {
escfunc(e, n)
}
}
......@@ -457,9 +456,9 @@ func escAnalyze(all *NodeList, recursive bool) {
}
// for all top level functions, tag the typenodes corresponding to the param nodes
for l := all; l != nil; l = l.Next {
if l.N.Op == ODCLFUNC {
esctag(e, l.N)
for i := len(all) - 1; i >= 0; i-- {
if n := all[i]; n.Op == ODCLFUNC {
esctag(e, n)
}
}
......
......@@ -437,11 +437,13 @@ func Main() {
if Debug['l'] != 0 {
// Find functions that can be inlined and clone them before walk expands them.
visitBottomUp(xtop, func(list *NodeList, recursive bool) {
for l := list; l != nil; l = l.Next {
if l.N.Op == ODCLFUNC {
caninl(l.N)
inlcalls(l.N)
visitBottomUp(xtop, func(list []*Node, recursive bool) {
// TODO: use a range statement here if the order does not matter
for i := len(list) - 1; i >= 0; i-- {
n := list[i]
if n.Op == ODCLFUNC {
caninl(n)
inlcalls(n)
}
}
})
......
......@@ -2499,7 +2499,7 @@ func genwrapper(rcvr *Type, method *Type, newnam *Sym, iface int) {
typechecklist(fn.Nbody, Etop)
inlcalls(fn)
escAnalyze(list1(fn), false)
escAnalyze([]*Node{fn}, false)
Curfn = nil
funccompile(fn)
......
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