1
0
mirror of https://github.com/golang/go synced 2024-11-22 18:54:44 -07:00

[dev.regabi] cmd/compile: change NodeSet to NameSet

The only user of NodeSet (computing initialization dependencies) only
needs to store *Names in this structure. So change its definition to
match that need, and update the code in initorder.go accordingly.

Passes buildall w/ toolstash -cmp.

Updates #42982.

Change-Id: I181a8aaf9bc71e88f4ac009c4f381a718080e48f
Reviewed-on: https://go-review.googlesource.com/c/go/+/275752
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Matthew Dempsky 2020-12-05 15:49:03 -08:00
parent 46b6e70e3b
commit 6c5967e528
2 changed files with 18 additions and 18 deletions

View File

@ -110,7 +110,7 @@ func initOrder(l []ir.Node) []ir.Node {
// first. // first.
base.ExitIfErrors() base.ExitIfErrors()
findInitLoopAndExit(firstLHS(n), new([]ir.Node)) findInitLoopAndExit(firstLHS(n), new([]*ir.Name))
base.Fatalf("initialization unfinished, but failed to identify loop") base.Fatalf("initialization unfinished, but failed to identify loop")
} }
} }
@ -136,7 +136,7 @@ func (o *InitOrder) processAssign(n ir.Node) {
// Compute number of variable dependencies and build the // Compute number of variable dependencies and build the
// inverse dependency ("blocking") graph. // inverse dependency ("blocking") graph.
for dep := range collectDeps(n, true) { for dep := range collectDeps(n, true) {
defn := dep.Name().Defn defn := dep.Defn
// Skip dependencies on functions (PFUNC) and // Skip dependencies on functions (PFUNC) and
// variables already initialized (InitDone). // variables already initialized (InitDone).
if dep.Class() != ir.PEXTERN || defn.Initorder() == InitDone { if dep.Class() != ir.PEXTERN || defn.Initorder() == InitDone {
@ -183,7 +183,7 @@ func (o *InitOrder) flushReady(initialize func(ir.Node)) {
// path points to a slice used for tracking the sequence of // path points to a slice used for tracking the sequence of
// variables/functions visited. Using a pointer to a slice allows the // variables/functions visited. Using a pointer to a slice allows the
// slice capacity to grow and limit reallocations. // slice capacity to grow and limit reallocations.
func findInitLoopAndExit(n ir.Node, path *[]ir.Node) { func findInitLoopAndExit(n *ir.Name, path *[]*ir.Name) {
// We implement a simple DFS loop-finding algorithm. This // We implement a simple DFS loop-finding algorithm. This
// could be faster, but initialization cycles are rare. // could be faster, but initialization cycles are rare.
@ -196,14 +196,14 @@ func findInitLoopAndExit(n ir.Node, path *[]ir.Node) {
// There might be multiple loops involving n; by sorting // There might be multiple loops involving n; by sorting
// references, we deterministically pick the one reported. // references, we deterministically pick the one reported.
refers := collectDeps(n.Name().Defn, false).Sorted(func(ni, nj ir.Node) bool { refers := collectDeps(n.Name().Defn, false).Sorted(func(ni, nj *ir.Name) bool {
return ni.Pos().Before(nj.Pos()) return ni.Pos().Before(nj.Pos())
}) })
*path = append(*path, n) *path = append(*path, n)
for _, ref := range refers { for _, ref := range refers {
// Short-circuit variables that were initialized. // Short-circuit variables that were initialized.
if ref.Class() == ir.PEXTERN && ref.Name().Defn.Initorder() == InitDone { if ref.Class() == ir.PEXTERN && ref.Defn.Initorder() == InitDone {
continue continue
} }
@ -215,7 +215,7 @@ func findInitLoopAndExit(n ir.Node, path *[]ir.Node) {
// reportInitLoopAndExit reports and initialization loop as an error // reportInitLoopAndExit reports and initialization loop as an error
// and exits. However, if l is not actually an initialization loop, it // and exits. However, if l is not actually an initialization loop, it
// simply returns instead. // simply returns instead.
func reportInitLoopAndExit(l []ir.Node) { func reportInitLoopAndExit(l []*ir.Name) {
// Rotate loop so that the earliest variable declaration is at // Rotate loop so that the earliest variable declaration is at
// the start. // the start.
i := -1 i := -1
@ -250,7 +250,7 @@ func reportInitLoopAndExit(l []ir.Node) {
// variables that declaration n depends on. If transitive is true, // variables that declaration n depends on. If transitive is true,
// then it also includes the transitive dependencies of any depended // then it also includes the transitive dependencies of any depended
// upon functions (but not variables). // upon functions (but not variables).
func collectDeps(n ir.Node, transitive bool) ir.NodeSet { func collectDeps(n ir.Node, transitive bool) ir.NameSet {
d := initDeps{transitive: transitive} d := initDeps{transitive: transitive}
switch n.Op() { switch n.Op() {
case ir.OAS: case ir.OAS:
@ -267,7 +267,7 @@ func collectDeps(n ir.Node, transitive bool) ir.NodeSet {
type initDeps struct { type initDeps struct {
transitive bool transitive bool
seen ir.NodeSet seen ir.NameSet
} }
func (d *initDeps) inspect(n ir.Node) { ir.Inspect(n, d.visit) } func (d *initDeps) inspect(n ir.Node) { ir.Inspect(n, d.visit) }
@ -345,12 +345,12 @@ func (s *declOrder) Pop() interface{} {
// firstLHS returns the first expression on the left-hand side of // firstLHS returns the first expression on the left-hand side of
// assignment n. // assignment n.
func firstLHS(n ir.Node) ir.Node { func firstLHS(n ir.Node) *ir.Name {
switch n.Op() { switch n.Op() {
case ir.OAS: case ir.OAS:
return n.Left() return n.Left().Name()
case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2RECV, ir.OAS2MAPR: case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2RECV, ir.OAS2MAPR:
return n.List().First() return n.List().First().Name()
} }
base.Fatalf("unexpected Op: %v", n.Op()) base.Fatalf("unexpected Op: %v", n.Op())

View File

@ -585,26 +585,26 @@ func (q *NodeQueue) PopLeft() Node {
return n return n
} }
// NodeSet is a set of Nodes. // NameSet is a set of Names.
type NodeSet map[Node]struct{} type NameSet map[*Name]struct{}
// Has reports whether s contains n. // Has reports whether s contains n.
func (s NodeSet) Has(n Node) bool { func (s NameSet) Has(n *Name) bool {
_, isPresent := s[n] _, isPresent := s[n]
return isPresent return isPresent
} }
// Add adds n to s. // Add adds n to s.
func (s *NodeSet) Add(n Node) { func (s *NameSet) Add(n *Name) {
if *s == nil { if *s == nil {
*s = make(map[Node]struct{}) *s = make(map[*Name]struct{})
} }
(*s)[n] = struct{}{} (*s)[n] = struct{}{}
} }
// Sorted returns s sorted according to less. // Sorted returns s sorted according to less.
func (s NodeSet) Sorted(less func(Node, Node) bool) []Node { func (s NameSet) Sorted(less func(*Name, *Name) bool) []*Name {
var res []Node var res []*Name
for n := range s { for n := range s {
res = append(res, n) res = append(res, n)
} }