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