]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: late call expansion for go func and simple defer func
authorDavid Chase <drchase@google.com>
Tue, 11 Aug 2020 12:39:17 +0000 (08:39 -0400)
committerDavid Chase <drchase@google.com>
Thu, 1 Oct 2020 17:49:01 +0000 (17:49 +0000)
Passes run.bash and race.bash on darwin/amd64.

Change-Id: Icbccaa2f2e7c3eac7c328c5253f331e598e11542
Reviewed-on: https://go-review.googlesource.com/c/go/+/247898
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/gc/ssa.go

index 7e377f9b84455c13f2ffd22e661efde17d0ae61a..7effa9bd4b1ff53fc51a6a8b0cdf57b581844308 100644 (file)
@@ -4374,11 +4374,11 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
 
        switch n.Op {
        case OCALLFUNC:
+               if k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) {
+                       testLateExpansion = true
+               }
                if k == callNormal && fn.Op == ONAME && fn.Class() == PFUNC {
                        sym = fn.Sym
-                       if ssa.LateCallExpansionEnabledWithin(s.f) {
-                               testLateExpansion = true
-                       }
                        break
                }
                closure = s.expr(fn)
@@ -4386,19 +4386,16 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                        // Deferred nil function needs to panic when the function is invoked,
                        // not the point of defer statement.
                        s.maybeNilCheckClosure(closure, k)
-                       if k == callNormal && ssa.LateCallExpansionEnabledWithin(s.f) {
-                               testLateExpansion = true
-                       }
                }
        case OCALLMETH:
                if fn.Op != ODOTMETH {
                        s.Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn)
                }
+               if k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) {
+                       testLateExpansion = true
+               }
                if k == callNormal {
                        sym = fn.Sym
-                       if ssa.LateCallExpansionEnabledWithin(s.f) {
-                               testLateExpansion = true
-                       }
                        break
                }
                closure = s.getMethodClosure(fn)
@@ -4408,13 +4405,13 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                if fn.Op != ODOTINTER {
                        s.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op)
                }
+               if k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f) {
+                       testLateExpansion = true
+               }
                var iclosure *ssa.Value
                iclosure, rcvr = s.getClosureAndRcvr(fn)
                if k == callNormal {
                        codeptr = s.load(types.Types[TUINTPTR], iclosure)
-                       if ssa.LateCallExpansionEnabledWithin(s.f) {
-                               testLateExpansion = true
-                       }
                } else {
                        closure = iclosure
                }
@@ -4549,9 +4546,21 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                // call target
                switch {
                case k == callDefer:
-                       call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, ssa.StaticAuxCall(deferproc, ACArgs, ACResults), s.mem())
+                       aux := ssa.StaticAuxCall(deferproc, ACArgs, ACResults)
+                       if testLateExpansion {
+                               call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
+                               call.AddArgs(callArgs...)
+                       } else {
+                               call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
+                       }
                case k == callGo:
-                       call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, ssa.StaticAuxCall(newproc, ACArgs, ACResults), s.mem())
+                       aux := ssa.StaticAuxCall(newproc, ACArgs, ACResults)
+                       if testLateExpansion {
+                               call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
+                               call.AddArgs(callArgs...)
+                       } else {
+                               call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
+                       }
                case closure != nil:
                        // rawLoad because loading the code pointer from a
                        // closure is always safe, but IsSanitizerSafeAddr