Skip to content

cmd/compile: refactor generic visitor code #42981

@mdempsky

Description

@mdempsky

There's a bunch of implementations of ad hoc, generic IR tree walking code within the compiler frontend.

Examples:

if n.Left() != nil && hasCall(n.Left()) {
return true
}
if n.Right() != nil && hasCall(n.Right()) {
return true
}
for _, x := range n.Init().Slice() {
if hasCall(x) {
return true
}
}
for _, x := range n.Body().Slice() {
if hasCall(x) {
return true
}
}
for _, x := range n.List().Slice() {
if hasCall(x) {
return true
}
}
for _, x := range n.Rlist().Slice() {
if hasCall(x) {
return true
}
}

if hascallchan(n.Left()) || hascallchan(n.Right()) {
return true
}
for _, n1 := range n.List().Slice() {
if hascallchan(n1) {
return true
}
}
for _, n2 := range n.Rlist().Slice() {

return v.visit(n.Left()) || v.visit(n.Right()) ||
v.visitList(n.List()) || v.visitList(n.Rlist()) ||
v.visitList(n.Init()) || v.visitList(n.Body())

cnt += countNodes(n.Left())
cnt += countNodes(n.Right())
for _, n1 := range n.Init().Slice() {
cnt += countNodes(n1)
}
for _, n1 := range n.Body().Slice() {
cnt += countNodes(n1)
}
for _, n1 := range n.List().Slice() {
cnt += countNodes(n1)
}
for _, n1 := range n.Rlist().Slice() {
cnt += countNodes(n1)
}

if a := v.visit(n.Left()); a != nil {
return a
}
if a := v.visit(n.Right()); a != nil {
return a
}
if a := v.visitList(n.List()); a != nil {
return a
}
if a := v.visitList(n.Rlist()); a != nil {
return a
}
if a := v.visitList(n.Init()); a != nil {
return a
}
if a := v.visitList(n.Body()); a != nil {
return a
}

markbreak(labels, n.Left(), implicit)
markbreak(labels, n.Right(), implicit)
markbreaklist(labels, n.Init(), implicit)
markbreaklist(labels, n.Body(), implicit)
markbreaklist(labels, n.List(), implicit)
markbreaklist(labels, n.Rlist(), implicit)

It should be possible to rewrite a lot of this code to use ir.Inspect or ir.InspectList instead. This will eventually be helpful for getting rid of the generic Left/Right/etc methods.

For the markbreak case (and maybe others), it might be useful to provide ir analogs to ast.Walk and ast.Visitor. (See also how ast.Inspect is implemented, as that API was inspirational for ir.Inspect.)

/cc @cuonglm

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.SuggestedIssues that may be good for new contributors looking for work to do.help wanted

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions