]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: move hasdefer to Func
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 16 Mar 2017 05:55:21 +0000 (22:55 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 17 Mar 2017 04:56:11 +0000 (04:56 +0000)
Passes toolstash -cmp.

Updates #15756

Change-Id: Ia071dbbd7f2ee0f8433d8c37af4f7b588016244e
Reviewed-on: https://go-review.googlesource.com/38231
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/pgen.go
src/cmd/compile/internal/gc/plive.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/walk.go

index 95c7dabc454b29bd55034fd71cc3a7403e8073cc..ecdbd1d9a1630a149f71b123aed073d8c0541865 100644 (file)
@@ -251,8 +251,6 @@ var Stksize int64 // stack size for current frame
 
 var stkptrsize int64 // prefix of stack containing pointers
 
-var hasdefer bool // flag that curfn has defer statement
-
 var Curfn *Node
 
 var Widthptr int
index 3fefe67fdfee7d993f9af8cf752f5ac1b0b02e42..d5978bb23916f8acdc7e77932daca726f35a89e6 100644 (file)
@@ -340,7 +340,6 @@ func compile(fn *Node) {
                return
        }
 
-       hasdefer = false
        walk(fn)
        if nerrors != 0 {
                return
index ec8de83c51d840e04789a62df1f2d483df71049b..e8447e4e68629358099b3b646e789a03de8cf68f 100644 (file)
@@ -1092,7 +1092,7 @@ func livenessepilogue(lv *Liveness) {
        // pointers to copy values back to the stack).
        // TODO: if the output parameter is heap-allocated, then we
        // don't need to keep the stack copy live?
-       if hasdefer {
+       if lv.fn.Func.HasDefer() {
                for i, n := range lv.vars {
                        if n.Class == PPARAMOUT {
                                if n.IsOutputParamHeapAddr() {
index 418056a81ca9d9715ae227393350f4d3ff3b13e8..8f61590864460214568b8f1bb4e665201ee1dfe0 100644 (file)
@@ -47,6 +47,7 @@ func buildssa(fn *Node) *ssa.Func {
        s.pushLine(fn.Pos)
        defer s.popLine()
 
+       s.hasdefer = fn.Func.HasDefer()
        if fn.Func.Pragma&CgoUnsafeArgs != 0 {
                s.cgoUnsafeArgs = true
        }
@@ -218,6 +219,7 @@ type state struct {
        placeholder *ssa.Value
 
        cgoUnsafeArgs bool
+       hasdefer      bool // whether the function contains a defer statement
 }
 
 type funcLine struct {
@@ -877,7 +879,7 @@ func (s *state) stmt(n *Node) {
 // It returns a BlockRet block that ends the control flow. Its control value
 // will be set to the final memory state.
 func (s *state) exit() *ssa.Block {
-       if hasdefer {
+       if s.hasdefer {
                s.rtcall(Deferreturn, true, nil)
        }
 
@@ -3189,7 +3191,7 @@ func (s *state) canSSA(n *Node) bool {
        case PEXTERN:
                return false
        case PPARAMOUT:
-               if hasdefer {
+               if s.hasdefer {
                        // TODO: handle this case?  Named return values must be
                        // in memory so that the deferred function can see them.
                        // Maybe do: if !strings.HasPrefix(n.String(), "~") { return false }
index 5399a03dabe85990c879e058f52e3ea5e873d2fa..eb610119aed251e5c8a58fcbb1a66984ce24e3bf 100644 (file)
@@ -342,6 +342,7 @@ const (
        funcReflectMethod             // function calls reflect.Type.Method or MethodByName
        funcIsHiddenClosure
        funcNoFramePointer // Must not use a frame pointer for this function
+       funcHasDefer       // contains a defer statement
 )
 
 func (f *Func) Dupok() bool           { return f.flags&funcDupok != 0 }
@@ -350,6 +351,7 @@ func (f *Func) Needctxt() bool        { return f.flags&funcNeedctxt != 0 }
 func (f *Func) ReflectMethod() bool   { return f.flags&funcReflectMethod != 0 }
 func (f *Func) IsHiddenClosure() bool { return f.flags&funcIsHiddenClosure != 0 }
 func (f *Func) NoFramePointer() bool  { return f.flags&funcNoFramePointer != 0 }
+func (f *Func) HasDefer() bool        { return f.flags&funcHasDefer != 0 }
 
 func (f *Func) SetDupok(b bool)           { f.flags.set(funcDupok, b) }
 func (f *Func) SetWrapper(b bool)         { f.flags.set(funcWrapper, b) }
@@ -357,6 +359,7 @@ func (f *Func) SetNeedctxt(b bool)        { f.flags.set(funcNeedctxt, b) }
 func (f *Func) SetReflectMethod(b bool)   { f.flags.set(funcReflectMethod, b) }
 func (f *Func) SetIsHiddenClosure(b bool) { f.flags.set(funcIsHiddenClosure, b) }
 func (f *Func) SetNoFramePointer(b bool)  { f.flags.set(funcNoFramePointer, b) }
+func (f *Func) SetHasDefer(b bool)        { f.flags.set(funcHasDefer, b) }
 
 type Op uint8
 
index 0c233c24c63edb9325b305605c6c56a3698059a0..5db29bdca974d5c54e2d6fef01d3c2be9e7ea56f 100644 (file)
@@ -247,7 +247,7 @@ func walkstmt(n *Node) *Node {
                n.Right = walkstmt(n.Right)
 
        case ODEFER:
-               hasdefer = true
+               Curfn.Func.SetHasDefer(true)
                switch n.Left.Op {
                case OPRINT, OPRINTN:
                        n.Left = walkprintfunc(n.Left, &n.Ninit)