]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: add Name.Canonical and move Byval
authorMatthew Dempsky <mdempsky@google.com>
Tue, 5 Jan 2021 14:43:38 +0000 (06:43 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 5 Jan 2021 15:42:33 +0000 (15:42 +0000)
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>
src/cmd/compile/internal/dwarfgen/dwarf.go
src/cmd/compile/internal/escape/escape.go
src/cmd/compile/internal/ir/expr.go
src/cmd/compile/internal/ir/name.go
src/cmd/compile/internal/typecheck/func.go

index 1534adaac8e66058c9fa2e313fed01f0819e6b65..ff249c1f4ecc35b80d5e49f5b035a39c75fa3e91 100644 (file)
@@ -127,10 +127,7 @@ func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope,
 }
 
 func declPos(decl *ir.Name) src.XPos {
-       if decl.IsClosureVar() {
-               decl = decl.Defn.(*ir.Name)
-       }
-       return decl.Pos()
+       return decl.Canonical().Pos()
 }
 
 // createDwarfVars process fn, returning a list of DWARF variables and the
index 6a2e685fe87ebf5a2bc3c52fdea2bd130c38b215..794c52f5ae3f81adc086c838afc04ef4115acdb5 100644 (file)
@@ -1146,19 +1146,6 @@ func (e *escape) later(k hole) hole {
        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 {
        if e.curfn == nil {
                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())
        }
 
-       n = canonicalNode(n)
+       if n != nil && n.Op() == ir.ONAME {
+               n = n.(*ir.Name).Canonical()
+       }
        loc := &location{
                n:         n,
                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 {
-       n = canonicalNode(n).(*ir.Name)
-       return n.Opt.(*location)
+       return n.Canonical().Opt.(*location)
 }
 
 func (l *location) asHole() hole {
index 77b6c8a1037de75b9eb6351806ec881e7fe62312..e7aa9c6a8f06d572aff3c9e1536a1f237ac1778d 100644 (file)
@@ -829,14 +829,9 @@ func reassigned(name *Name) bool {
        // reassignment detection for use by inlining and devirtualization.
 
        // isName reports whether n is a reference to name.
-       isName := func(n Node) bool {
-               if n, ok := n.(*Name); ok && n.Op() == ONAME {
-                       if n.IsClosureVar() && n.Defn != nil {
-                               n = n.Defn.(*Name)
-                       }
-                       return n == name
-               }
-               return false
+       isName := func(x Node) bool {
+               n, ok := x.(*Name)
+               return ok && n.Canonical() == name
        }
 
        var do func(n Node) bool
index 58b4ababff9dc3115a3f4473bab14321d7226f53..9d7d376ba50d07bfbba5274bb38966cec9c8c5ab 100644 (file)
@@ -279,7 +279,6 @@ const (
 
 func (n *Name) Captured() bool              { return n.flags&nameCaptured != 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) AutoTemp() bool              { return n.flags&nameAutoTemp != 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) 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) SetAutoTemp(b bool)              { n.flags.set(nameAutoTemp, 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
 }
 
+// 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
 // element.
 //
index e4c308822521c189cfe15649a032f2b97e1b3a9f..8fdb33b1452e81570a3d89603169012d6c3ce61c 100644 (file)
@@ -110,8 +110,8 @@ func CaptureVars(fn *ir.Func) {
                outermost := v.Defn.(*ir.Name)
 
                // out parameters will be assigned to implicitly upon return.
-               if outermost.Class != ir.PPARAMOUT && !outermost.Addrtaken() && !outermost.Assigned() && v.Type().Size() <= 128 {
-                       v.SetByval(true)
+               if outermost.Class != ir.PPARAMOUT && !outermost.Addrtaken() && !outermost.Assigned() && outermost.Type().Size() <= 128 {
+                       outermost.SetByval(true)
                } else {
                        outermost.SetAddrtaken(true)
                }