mirror of
https://github.com/golang/go
synced 2024-11-26 08:27:56 -07:00
[dev.regabi] cmd/compile: add Name.Canonical and move Byval
There's a bunch of code that wants to map closure variables back to their original name, so add a single Name.Canonical method that they can all use. Also, move the Byval flag from being stored on individual closure variables to being stored on the canonical variable. Passes toolstash -cmp. Change-Id: Ia3ef81af5a15783d09f04b4e274ce33df94518e6 Reviewed-on: https://go-review.googlesource.com/c/go/+/281541 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
e09783cbc0
commit
77365c5ed7
@ -127,10 +127,7 @@ func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func declPos(decl *ir.Name) src.XPos {
|
func declPos(decl *ir.Name) src.XPos {
|
||||||
if decl.IsClosureVar() {
|
return decl.Canonical().Pos()
|
||||||
decl = decl.Defn.(*ir.Name)
|
|
||||||
}
|
|
||||||
return decl.Pos()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// createDwarfVars process fn, returning a list of DWARF variables and the
|
// createDwarfVars process fn, returning a list of DWARF variables and the
|
||||||
|
@ -1146,19 +1146,6 @@ func (e *escape) later(k hole) hole {
|
|||||||
return loc.asHole()
|
return loc.asHole()
|
||||||
}
|
}
|
||||||
|
|
||||||
// canonicalNode returns the canonical *Node that n logically
|
|
||||||
// represents.
|
|
||||||
func canonicalNode(n ir.Node) ir.Node {
|
|
||||||
if n != nil && n.Op() == ir.ONAME && n.Name().IsClosureVar() {
|
|
||||||
n = n.Name().Defn
|
|
||||||
if n.Name().IsClosureVar() {
|
|
||||||
base.Fatalf("still closure var")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *escape) newLoc(n ir.Node, transient bool) *location {
|
func (e *escape) newLoc(n ir.Node, transient bool) *location {
|
||||||
if e.curfn == nil {
|
if e.curfn == nil {
|
||||||
base.Fatalf("e.curfn isn't set")
|
base.Fatalf("e.curfn isn't set")
|
||||||
@ -1167,7 +1154,9 @@ func (e *escape) newLoc(n ir.Node, transient bool) *location {
|
|||||||
base.ErrorfAt(n.Pos(), "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type())
|
base.ErrorfAt(n.Pos(), "%v is incomplete (or unallocatable); stack allocation disallowed", n.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
n = canonicalNode(n)
|
if n != nil && n.Op() == ir.ONAME {
|
||||||
|
n = n.(*ir.Name).Canonical()
|
||||||
|
}
|
||||||
loc := &location{
|
loc := &location{
|
||||||
n: n,
|
n: n,
|
||||||
curfn: e.curfn,
|
curfn: e.curfn,
|
||||||
@ -1196,8 +1185,7 @@ func (e *escape) newLoc(n ir.Node, transient bool) *location {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *batch) oldLoc(n *ir.Name) *location {
|
func (b *batch) oldLoc(n *ir.Name) *location {
|
||||||
n = canonicalNode(n).(*ir.Name)
|
return n.Canonical().Opt.(*location)
|
||||||
return n.Opt.(*location)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *location) asHole() hole {
|
func (l *location) asHole() hole {
|
||||||
|
@ -829,14 +829,9 @@ func reassigned(name *Name) bool {
|
|||||||
// reassignment detection for use by inlining and devirtualization.
|
// reassignment detection for use by inlining and devirtualization.
|
||||||
|
|
||||||
// isName reports whether n is a reference to name.
|
// isName reports whether n is a reference to name.
|
||||||
isName := func(n Node) bool {
|
isName := func(x Node) bool {
|
||||||
if n, ok := n.(*Name); ok && n.Op() == ONAME {
|
n, ok := x.(*Name)
|
||||||
if n.IsClosureVar() && n.Defn != nil {
|
return ok && n.Canonical() == name
|
||||||
n = n.Defn.(*Name)
|
|
||||||
}
|
|
||||||
return n == name
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var do func(n Node) bool
|
var do func(n Node) bool
|
||||||
|
@ -279,7 +279,6 @@ const (
|
|||||||
|
|
||||||
func (n *Name) Captured() bool { return n.flags&nameCaptured != 0 }
|
func (n *Name) Captured() bool { return n.flags&nameCaptured != 0 }
|
||||||
func (n *Name) Readonly() bool { return n.flags&nameReadonly != 0 }
|
func (n *Name) Readonly() bool { return n.flags&nameReadonly != 0 }
|
||||||
func (n *Name) Byval() bool { return n.flags&nameByval != 0 }
|
|
||||||
func (n *Name) Needzero() bool { return n.flags&nameNeedzero != 0 }
|
func (n *Name) Needzero() bool { return n.flags&nameNeedzero != 0 }
|
||||||
func (n *Name) AutoTemp() bool { return n.flags&nameAutoTemp != 0 }
|
func (n *Name) AutoTemp() bool { return n.flags&nameAutoTemp != 0 }
|
||||||
func (n *Name) Used() bool { return n.flags&nameUsed != 0 }
|
func (n *Name) Used() bool { return n.flags&nameUsed != 0 }
|
||||||
@ -294,7 +293,6 @@ func (n *Name) LibfuzzerExtraCounter() bool { return n.flags&nameLibfuzzerExtraC
|
|||||||
|
|
||||||
func (n *Name) SetCaptured(b bool) { n.flags.set(nameCaptured, b) }
|
func (n *Name) SetCaptured(b bool) { n.flags.set(nameCaptured, b) }
|
||||||
func (n *Name) setReadonly(b bool) { n.flags.set(nameReadonly, b) }
|
func (n *Name) setReadonly(b bool) { n.flags.set(nameReadonly, b) }
|
||||||
func (n *Name) SetByval(b bool) { n.flags.set(nameByval, b) }
|
|
||||||
func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) }
|
func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) }
|
||||||
func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) }
|
func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) }
|
||||||
func (n *Name) SetUsed(b bool) { n.flags.set(nameUsed, b) }
|
func (n *Name) SetUsed(b bool) { n.flags.set(nameUsed, b) }
|
||||||
@ -336,6 +334,33 @@ func (n *Name) SetVal(v constant.Value) {
|
|||||||
n.val = v
|
n.val = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Canonical returns the logical declaration that n represents. If n
|
||||||
|
// is a closure variable, then Canonical returns the original Name as
|
||||||
|
// it appears in the function that immediately contains the
|
||||||
|
// declaration. Otherwise, Canonical simply returns n itself.
|
||||||
|
func (n *Name) Canonical() *Name {
|
||||||
|
if n.IsClosureVar() {
|
||||||
|
n = n.Defn.(*Name)
|
||||||
|
if n.IsClosureVar() {
|
||||||
|
base.Fatalf("recursive closure variable: %v", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Name) SetByval(b bool) {
|
||||||
|
if n.Canonical() != n {
|
||||||
|
base.Fatalf("SetByval called on non-canonical variable: %v", n)
|
||||||
|
}
|
||||||
|
n.flags.set(nameByval, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Name) Byval() bool {
|
||||||
|
// We require byval to be set on the canonical variable, but we
|
||||||
|
// allow it to be accessed from any instance.
|
||||||
|
return n.Canonical().flags&nameByval != 0
|
||||||
|
}
|
||||||
|
|
||||||
// SameSource reports whether two nodes refer to the same source
|
// SameSource reports whether two nodes refer to the same source
|
||||||
// element.
|
// element.
|
||||||
//
|
//
|
||||||
|
@ -110,8 +110,8 @@ func CaptureVars(fn *ir.Func) {
|
|||||||
outermost := v.Defn.(*ir.Name)
|
outermost := v.Defn.(*ir.Name)
|
||||||
|
|
||||||
// out parameters will be assigned to implicitly upon return.
|
// out parameters will be assigned to implicitly upon return.
|
||||||
if outermost.Class != ir.PPARAMOUT && !outermost.Addrtaken() && !outermost.Assigned() && v.Type().Size() <= 128 {
|
if outermost.Class != ir.PPARAMOUT && !outermost.Addrtaken() && !outermost.Assigned() && outermost.Type().Size() <= 128 {
|
||||||
v.SetByval(true)
|
outermost.SetByval(true)
|
||||||
} else {
|
} else {
|
||||||
outermost.SetAddrtaken(true)
|
outermost.SetAddrtaken(true)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user