[dev.regabi] cmd/compile: move gc.treecopy to ir.DeepCopy

This is a general operation on IR nodes, so it belongs in ir.
The copied implementation is adapted to support the
extension pattern, allowing nodes to implement their
own DeepCopy implementations if needed.

This is the first step toward higher-level operations instead
of Left, Right, etc. It will allow the new type syntax nodes
to be properly immutable and opt out of those fine-grained methods.

Passes buildall w/ toolstash -cmp.

Change-Id: Ibd64061e01daf14aebc6586cb2eb2b12057ca85a
Reviewed-on: https://go-review.googlesource.com/c/go/+/274102
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Russ Cox 2020-11-29 09:38:52 -05:00
parent f0001e8867
commit d40869fced
5 changed files with 133 additions and 101 deletions

View file

@ -181,42 +181,6 @@ func nodstr(s string) ir.Node {
return ir.NewLiteral(constant.MakeString(s))
}
// treecopy recursively copies n, with the exception of
// ONAME, OLITERAL, OTYPE, and ONONAME leaves.
// If pos.IsKnown(), it sets the source position of newly
// allocated nodes to pos.
func treecopy(n ir.Node, pos src.XPos) ir.Node {
if n == nil {
return nil
}
switch n.Op() {
default:
m := ir.SepCopy(n)
m.SetLeft(treecopy(n.Left(), pos))
m.SetRight(treecopy(n.Right(), pos))
m.PtrList().Set(listtreecopy(n.List().Slice(), pos))
if pos.IsKnown() {
m.SetPos(pos)
}
if m.Name() != nil && n.Op() != ir.ODCLFIELD {
ir.Dump("treecopy", n)
base.Fatalf("treecopy Name")
}
return m
case ir.OPACK:
// OPACK nodes are never valid in const value declarations,
// but allow them like any other declared symbol to avoid
// crashing (golang.org/issue/11361).
fallthrough
case ir.ONAME, ir.ONONAME, ir.OLITERAL, ir.ONIL, ir.OTYPE:
return n
}
}
func isptrto(t *types.Type, et types.EType) bool {
if t == nil {
return false
@ -1375,14 +1339,6 @@ func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool
return true
}
func listtreecopy(l []ir.Node, pos src.XPos) []ir.Node {
var out []ir.Node
for _, n := range l {
out = append(out, treecopy(n, pos))
}
return out
}
func liststmt(l []ir.Node) ir.Node {
n := ir.Nod(ir.OBLOCK, nil, nil)
n.PtrList().Set(l)