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.lastDeferExit = deferExit
|
||||||
s.lastDeferCount = len(s.openDefers)
|
s.lastDeferCount = len(s.openDefers)
|
||||||
zeroval := s.constInt8(types.Types[TUINT8], 0)
|
zeroval := s.constInt8(types.Types[TUINT8], 0)
|
||||||
|
testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
|
||||||
// Test for and run defers in reverse order
|
// Test for and run defers in reverse order
|
||||||
for i := len(s.openDefers) - 1; i >= 0; i-- {
|
for i := len(s.openDefers) - 1; i >= 0; i-- {
|
||||||
r := s.openDefers[i]
|
r := s.openDefers[i]
|
||||||
@ -4288,23 +4289,38 @@ func (s *state) openDeferExit() {
|
|||||||
stksize := fn.Type.ArgWidth()
|
stksize := fn.Type.ArgWidth()
|
||||||
var ACArgs []ssa.Param
|
var ACArgs []ssa.Param
|
||||||
var ACResults []ssa.Param
|
var ACResults []ssa.Param
|
||||||
|
var callArgs []*ssa.Value
|
||||||
if r.rcvr != nil {
|
if r.rcvr != nil {
|
||||||
// rcvr in case of OCALLINTER
|
// rcvr in case of OCALLINTER
|
||||||
v := s.load(r.rcvr.Type.Elem(), r.rcvr)
|
v := s.load(r.rcvr.Type.Elem(), r.rcvr)
|
||||||
addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
|
addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
|
||||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(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 {
|
for j, argAddrVal := range r.argVals {
|
||||||
f := getParam(r.n, j)
|
f := getParam(r.n, j)
|
||||||
pt := types.NewPtr(f.Type)
|
pt := types.NewPtr(f.Type)
|
||||||
addr := s.constOffPtrSP(pt, argStart+f.Offset)
|
ACArgs = append(ACArgs, ssa.Param{Type: f.Type, Offset: int32(argStart + f.Offset)})
|
||||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart + f.Offset)})
|
if testLateExpansion {
|
||||||
if !canSSAType(f.Type) {
|
var a *ssa.Value
|
||||||
s.move(f.Type, addr, argAddrVal)
|
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 {
|
} else {
|
||||||
argVal := s.load(f.Type, argAddrVal)
|
addr := s.constOffPtrSP(pt, argStart+f.Offset)
|
||||||
s.storeType(f.Type, addr, argVal, 0, false)
|
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
|
var call *ssa.Value
|
||||||
@ -4312,13 +4328,32 @@ func (s *state) openDeferExit() {
|
|||||||
v := s.load(r.closure.Type.Elem(), r.closure)
|
v := s.load(r.closure.Type.Elem(), r.closure)
|
||||||
s.maybeNilCheckClosure(v, callDefer)
|
s.maybeNilCheckClosure(v, callDefer)
|
||||||
codeptr := s.rawLoad(types.Types[TUINTPTR], v)
|
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 {
|
} else {
|
||||||
// Do a static call if the original call was a static function or method
|
aux := ssa.StaticAuxCall(fn.Sym.Linksym(), ACArgs, ACResults)
|
||||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, ssa.StaticAuxCall(fn.Sym.Linksym(), ACArgs, ACResults), s.mem())
|
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
|
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
|
// Make sure that the stack slots with pointers are kept live
|
||||||
// through the call (which is a pre-emption point). Also, we will
|
// through the call (which is a pre-emption point). Also, we will
|
||||||
// use the first call of the last defer exit to compute liveness
|
// use the first call of the last defer exit to compute liveness
|
||||||
|
Loading…
x
Reference in New Issue
Block a user