mirror of
https://github.com/golang/go.git
synced 2025-05-18 22:04:38 +00:00
cmd/compile: enable late expansion in openDeferExit
Change-Id: I4ce9e914d22b519b00d7e19d93091f6ac0b60938 Reviewed-on: https://go-review.googlesource.com/c/go/+/248188 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>
This commit is contained in:
parent
68bc950583
commit
bb46b60d29
@ -4251,6 +4251,7 @@ func (s *state) openDeferExit() {
|
||||
s.lastDeferExit = deferExit
|
||||
s.lastDeferCount = len(s.openDefers)
|
||||
zeroval := s.constInt8(types.Types[TUINT8], 0)
|
||||
testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
|
||||
// Test for and run defers in reverse order
|
||||
for i := len(s.openDefers) - 1; i >= 0; i-- {
|
||||
r := s.openDefers[i]
|
||||
@ -4288,23 +4289,38 @@ func (s *state) openDeferExit() {
|
||||
stksize := fn.Type.ArgWidth()
|
||||
var ACArgs []ssa.Param
|
||||
var ACResults []ssa.Param
|
||||
var callArgs []*ssa.Value
|
||||
if r.rcvr != nil {
|
||||
// rcvr in case of OCALLINTER
|
||||
v := s.load(r.rcvr.Type.Elem(), r.rcvr)
|
||||
addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart)})
|
||||
s.store(types.Types[TUINTPTR], addr, v)
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, v)
|
||||
} else {
|
||||
s.store(types.Types[TUINTPTR], addr, v)
|
||||
}
|
||||
}
|
||||
for j, argAddrVal := range r.argVals {
|
||||
f := getParam(r.n, j)
|
||||
pt := types.NewPtr(f.Type)
|
||||
addr := s.constOffPtrSP(pt, argStart+f.Offset)
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart + f.Offset)})
|
||||
if !canSSAType(f.Type) {
|
||||
s.move(f.Type, addr, argAddrVal)
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: f.Type, Offset: int32(argStart + f.Offset)})
|
||||
if testLateExpansion {
|
||||
var a *ssa.Value
|
||||
if !canSSAType(f.Type) {
|
||||
a = s.newValue2(ssa.OpDereference, f.Type, argAddrVal, s.mem())
|
||||
} else {
|
||||
a = s.load(f.Type, argAddrVal)
|
||||
}
|
||||
callArgs = append(callArgs, a)
|
||||
} else {
|
||||
argVal := s.load(f.Type, argAddrVal)
|
||||
s.storeType(f.Type, addr, argVal, 0, false)
|
||||
addr := s.constOffPtrSP(pt, argStart+f.Offset)
|
||||
if !canSSAType(f.Type) {
|
||||
s.move(f.Type, addr, argAddrVal)
|
||||
} else {
|
||||
argVal := s.load(f.Type, argAddrVal)
|
||||
s.storeType(f.Type, addr, argVal, 0, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
var call *ssa.Value
|
||||
@ -4312,13 +4328,32 @@ func (s *state) openDeferExit() {
|
||||
v := s.load(r.closure.Type.Elem(), r.closure)
|
||||
s.maybeNilCheckClosure(v, callDefer)
|
||||
codeptr := s.rawLoad(types.Types[TUINTPTR], v)
|
||||
call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, ssa.ClosureAuxCall(ACArgs, ACResults), codeptr, v, s.mem())
|
||||
aux := ssa.ClosureAuxCall(ACArgs, ACResults)
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, s.mem())
|
||||
call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, v)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, aux, codeptr, v, s.mem())
|
||||
}
|
||||
} else {
|
||||
// Do a static call if the original call was a static function or method
|
||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, ssa.StaticAuxCall(fn.Sym.Linksym(), ACArgs, ACResults), s.mem())
|
||||
aux := ssa.StaticAuxCall(fn.Sym.Linksym(), ACArgs, ACResults)
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, s.mem())
|
||||
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
// Do a static call if the original call was a static function or method
|
||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
|
||||
}
|
||||
}
|
||||
call.AuxInt = stksize
|
||||
s.vars[&memVar] = call
|
||||
if testLateExpansion {
|
||||
s.vars[&memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
|
||||
} else {
|
||||
s.vars[&memVar] = call
|
||||
}
|
||||
|
||||
// Make sure that the stack slots with pointers are kept live
|
||||
// through the call (which is a pre-emption point). Also, we will
|
||||
// use the first call of the last defer exit to compute liveness
|
||||
|
Loading…
x
Reference in New Issue
Block a user