]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: move addrescapes and moveToHeap to esc.go
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 27 Apr 2017 13:29:07 +0000 (06:29 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 27 Apr 2017 19:08:20 +0000 (19:08 +0000)
They were used only in esc.go. 100% code movement.

Also, remove the rather outdated comment at the top of gen.go.
It's not really clear what gen.go is for any more.

Change-Id: Iaedfe7015ef6f5c11c49f3e6721b15d779a00faa
Reviewed-on: https://go-review.googlesource.com/41971
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/gen.go

index aaf590da020ee663ba8e1746f2ea1d2a0f1d226f..29083ca6cbf1c1a4454655a3aff1e3493d1931fd 100644 (file)
@@ -2014,6 +2014,158 @@ recurse:
        e.pdepth--
 }
 
+// addrescapes tags node n as having had its address taken
+// by "increasing" the "value" of n.Esc to EscHeap.
+// Storage is allocated as necessary to allow the address
+// to be taken.
+func addrescapes(n *Node) {
+       switch n.Op {
+       default:
+               // Unexpected Op, probably due to a previous type error. Ignore.
+
+       case OIND, ODOTPTR:
+               // Nothing to do.
+
+       case ONAME:
+               if n == nodfp {
+                       break
+               }
+
+               // if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
+               // on PPARAM it means something different.
+               if n.Class() == PAUTO && n.Esc == EscNever {
+                       break
+               }
+
+               // If a closure reference escapes, mark the outer variable as escaping.
+               if n.IsClosureVar() {
+                       addrescapes(n.Name.Defn)
+                       break
+               }
+
+               if n.Class() != PPARAM && n.Class() != PPARAMOUT && n.Class() != PAUTO {
+                       break
+               }
+
+               // This is a plain parameter or local variable that needs to move to the heap,
+               // but possibly for the function outside the one we're compiling.
+               // That is, if we have:
+               //
+               //      func f(x int) {
+               //              func() {
+               //                      global = &x
+               //              }
+               //      }
+               //
+               // then we're analyzing the inner closure but we need to move x to the
+               // heap in f, not in the inner closure. Flip over to f before calling moveToHeap.
+               oldfn := Curfn
+               Curfn = n.Name.Curfn
+               if Curfn.Func.Closure != nil && Curfn.Op == OCLOSURE {
+                       Curfn = Curfn.Func.Closure
+               }
+               ln := lineno
+               lineno = Curfn.Pos
+               moveToHeap(n)
+               Curfn = oldfn
+               lineno = ln
+
+       // ODOTPTR has already been introduced,
+       // so these are the non-pointer ODOT and OINDEX.
+       // In &x[0], if x is a slice, then x does not
+       // escape--the pointer inside x does, but that
+       // is always a heap pointer anyway.
+       case ODOT, OINDEX, OPAREN, OCONVNOP:
+               if !n.Left.Type.IsSlice() {
+                       addrescapes(n.Left)
+               }
+       }
+}
+
+// moveToHeap records the parameter or local variable n as moved to the heap.
+func moveToHeap(n *Node) {
+       if Debug['r'] != 0 {
+               Dump("MOVE", n)
+       }
+       if compiling_runtime {
+               yyerror("%v escapes to heap, not allowed in runtime.", n)
+       }
+       if n.Class() == PAUTOHEAP {
+               Dump("n", n)
+               Fatalf("double move to heap")
+       }
+
+       // Allocate a local stack variable to hold the pointer to the heap copy.
+       // temp will add it to the function declaration list automatically.
+       heapaddr := temp(types.NewPtr(n.Type))
+       heapaddr.Sym = lookup("&" + n.Sym.Name)
+       heapaddr.Orig.Sym = heapaddr.Sym
+
+       // Unset AutoTemp to persist the &foo variable name through SSA to
+       // liveness analysis.
+       // TODO(mdempsky/drchase): Cleaner solution?
+       heapaddr.Name.SetAutoTemp(false)
+
+       // Parameters have a local stack copy used at function start/end
+       // in addition to the copy in the heap that may live longer than
+       // the function.
+       if n.Class() == PPARAM || n.Class() == PPARAMOUT {
+               if n.Xoffset == BADWIDTH {
+                       Fatalf("addrescapes before param assignment")
+               }
+
+               // We rewrite n below to be a heap variable (indirection of heapaddr).
+               // Preserve a copy so we can still write code referring to the original,
+               // and substitute that copy into the function declaration list
+               // so that analyses of the local (on-stack) variables use it.
+               stackcopy := newname(n.Sym)
+               stackcopy.SetAddable(false)
+               stackcopy.Type = n.Type
+               stackcopy.Xoffset = n.Xoffset
+               stackcopy.SetClass(n.Class())
+               stackcopy.Name.Param.Heapaddr = heapaddr
+               if n.Class() == PPARAMOUT {
+                       // Make sure the pointer to the heap copy is kept live throughout the function.
+                       // The function could panic at any point, and then a defer could recover.
+                       // Thus, we need the pointer to the heap copy always available so the
+                       // post-deferreturn code can copy the return value back to the stack.
+                       // See issue 16095.
+                       heapaddr.SetIsOutputParamHeapAddr(true)
+               }
+               n.Name.Param.Stackcopy = stackcopy
+
+               // Substitute the stackcopy into the function variable list so that
+               // liveness and other analyses use the underlying stack slot
+               // and not the now-pseudo-variable n.
+               found := false
+               for i, d := range Curfn.Func.Dcl {
+                       if d == n {
+                               Curfn.Func.Dcl[i] = stackcopy
+                               found = true
+                               break
+                       }
+                       // Parameters are before locals, so can stop early.
+                       // This limits the search even in functions with many local variables.
+                       if d.Class() == PAUTO {
+                               break
+                       }
+               }
+               if !found {
+                       Fatalf("cannot find %v in local variable list", n)
+               }
+               Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
+       }
+
+       // Modify n in place so that uses of n now mean indirection of the heapaddr.
+       n.SetClass(PAUTOHEAP)
+       n.Xoffset = 0
+       n.Name.Param.Heapaddr = heapaddr
+       n.Esc = EscHeap
+       if Debug['m'] != 0 {
+               fmt.Printf("%v: moved to heap: %v\n", n.Line(), n)
+       }
+}
+
 // This special tag is applied to uintptr variables
 // that we believe may hold unsafe.Pointers for
 // calls into assembly functions.
index 941c41502ae44c9c83b449e9bae6b9ee9231b3c5..09c04466d423129a6bddd65479ea6b891af064fe 100644 (file)
@@ -2,15 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Portable half of code generator; mainly statements and control flow.
-
 package gc
 
 import (
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/src"
-       "fmt"
        "strconv"
 )
 
@@ -18,74 +15,6 @@ func Sysfunc(name string) *obj.LSym {
        return Runtimepkg.Lookup(name).Linksym()
 }
 
-// addrescapes tags node n as having had its address taken
-// by "increasing" the "value" of n.Esc to EscHeap.
-// Storage is allocated as necessary to allow the address
-// to be taken.
-func addrescapes(n *Node) {
-       switch n.Op {
-       default:
-               // Unexpected Op, probably due to a previous type error. Ignore.
-
-       case OIND, ODOTPTR:
-               // Nothing to do.
-
-       case ONAME:
-               if n == nodfp {
-                       break
-               }
-
-               // if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
-               // on PPARAM it means something different.
-               if n.Class() == PAUTO && n.Esc == EscNever {
-                       break
-               }
-
-               // If a closure reference escapes, mark the outer variable as escaping.
-               if n.IsClosureVar() {
-                       addrescapes(n.Name.Defn)
-                       break
-               }
-
-               if n.Class() != PPARAM && n.Class() != PPARAMOUT && n.Class() != PAUTO {
-                       break
-               }
-
-               // This is a plain parameter or local variable that needs to move to the heap,
-               // but possibly for the function outside the one we're compiling.
-               // That is, if we have:
-               //
-               //      func f(x int) {
-               //              func() {
-               //                      global = &x
-               //              }
-               //      }
-               //
-               // then we're analyzing the inner closure but we need to move x to the
-               // heap in f, not in the inner closure. Flip over to f before calling moveToHeap.
-               oldfn := Curfn
-               Curfn = n.Name.Curfn
-               if Curfn.Func.Closure != nil && Curfn.Op == OCLOSURE {
-                       Curfn = Curfn.Func.Closure
-               }
-               ln := lineno
-               lineno = Curfn.Pos
-               moveToHeap(n)
-               Curfn = oldfn
-               lineno = ln
-
-       // ODOTPTR has already been introduced,
-       // so these are the non-pointer ODOT and OINDEX.
-       // In &x[0], if x is a slice, then x does not
-       // escape--the pointer inside x does, but that
-       // is always a heap pointer anyway.
-       case ODOT, OINDEX, OPAREN, OCONVNOP:
-               if !n.Left.Type.IsSlice() {
-                       addrescapes(n.Left)
-               }
-       }
-}
-
 // isParamStackCopy reports whether this is the on-stack copy of a
 // function parameter that moved to the heap.
 func (n *Node) isParamStackCopy() bool {
@@ -98,90 +27,6 @@ func (n *Node) isParamHeapCopy() bool {
        return n.Op == ONAME && n.Class() == PAUTOHEAP && n.Name.Param.Stackcopy != nil
 }
 
-// moveToHeap records the parameter or local variable n as moved to the heap.
-func moveToHeap(n *Node) {
-       if Debug['r'] != 0 {
-               Dump("MOVE", n)
-       }
-       if compiling_runtime {
-               yyerror("%v escapes to heap, not allowed in runtime.", n)
-       }
-       if n.Class() == PAUTOHEAP {
-               Dump("n", n)
-               Fatalf("double move to heap")
-       }
-
-       // Allocate a local stack variable to hold the pointer to the heap copy.
-       // temp will add it to the function declaration list automatically.
-       heapaddr := temp(types.NewPtr(n.Type))
-       heapaddr.Sym = lookup("&" + n.Sym.Name)
-       heapaddr.Orig.Sym = heapaddr.Sym
-
-       // Unset AutoTemp to persist the &foo variable name through SSA to
-       // liveness analysis.
-       // TODO(mdempsky/drchase): Cleaner solution?
-       heapaddr.Name.SetAutoTemp(false)
-
-       // Parameters have a local stack copy used at function start/end
-       // in addition to the copy in the heap that may live longer than
-       // the function.
-       if n.Class() == PPARAM || n.Class() == PPARAMOUT {
-               if n.Xoffset == BADWIDTH {
-                       Fatalf("addrescapes before param assignment")
-               }
-
-               // We rewrite n below to be a heap variable (indirection of heapaddr).
-               // Preserve a copy so we can still write code referring to the original,
-               // and substitute that copy into the function declaration list
-               // so that analyses of the local (on-stack) variables use it.
-               stackcopy := newname(n.Sym)
-               stackcopy.SetAddable(false)
-               stackcopy.Type = n.Type
-               stackcopy.Xoffset = n.Xoffset
-               stackcopy.SetClass(n.Class())
-               stackcopy.Name.Param.Heapaddr = heapaddr
-               if n.Class() == PPARAMOUT {
-                       // Make sure the pointer to the heap copy is kept live throughout the function.
-                       // The function could panic at any point, and then a defer could recover.
-                       // Thus, we need the pointer to the heap copy always available so the
-                       // post-deferreturn code can copy the return value back to the stack.
-                       // See issue 16095.
-                       heapaddr.SetIsOutputParamHeapAddr(true)
-               }
-               n.Name.Param.Stackcopy = stackcopy
-
-               // Substitute the stackcopy into the function variable list so that
-               // liveness and other analyses use the underlying stack slot
-               // and not the now-pseudo-variable n.
-               found := false
-               for i, d := range Curfn.Func.Dcl {
-                       if d == n {
-                               Curfn.Func.Dcl[i] = stackcopy
-                               found = true
-                               break
-                       }
-                       // Parameters are before locals, so can stop early.
-                       // This limits the search even in functions with many local variables.
-                       if d.Class() == PAUTO {
-                               break
-                       }
-               }
-               if !found {
-                       Fatalf("cannot find %v in local variable list", n)
-               }
-               Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
-       }
-
-       // Modify n in place so that uses of n now mean indirection of the heapaddr.
-       n.SetClass(PAUTOHEAP)
-       n.Xoffset = 0
-       n.Name.Param.Heapaddr = heapaddr
-       n.Esc = EscHeap
-       if Debug['m'] != 0 {
-               fmt.Printf("%v: moved to heap: %v\n", n.Line(), n)
-       }
-}
-
 // autotmpname returns the name for an autotmp variable numbered n.
 func autotmpname(n int) string {
        // Give each tmp a different name so that they can be registerized.