mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: update default ABI choices for calls and bodyless fn stack maps
After recent discussion about bodyless functions, their wrappers, their stack maps, nosplit, and callbacks, I was inspired to go and be sure that more defaults were sensible. This may not be all -- currently rtcall is "ABIDefault" which I think is correct, but I am not 100% certain. Updates #40724. Change-Id: I95b14ee0e5952fa53e7fea9f6f5192358aa24f23 Reviewed-on: https://go-review.googlesource.com/c/go/+/304549 Trust: David Chase <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
eeadfa2d38
commit
33945869c1
2 changed files with 21 additions and 18 deletions
|
|
@ -44,7 +44,7 @@ func enqueueFunc(fn *ir.Func) {
|
||||||
// Initialize ABI wrappers if necessary.
|
// Initialize ABI wrappers if necessary.
|
||||||
ssagen.InitLSym(fn, false)
|
ssagen.InitLSym(fn, false)
|
||||||
types.CalcSize(fn.Type()) // TODO register args; remove this once all is done by abiutils
|
types.CalcSize(fn.Type()) // TODO register args; remove this once all is done by abiutils
|
||||||
a := ssagen.AbiForFunc(fn)
|
a := ssagen.AbiForBodylessFuncStackMap(fn)
|
||||||
abiInfo := a.ABIAnalyze(fn.Type(), true) // will set parameter spill/home locations correctly
|
abiInfo := a.ABIAnalyze(fn.Type(), true) // will set parameter spill/home locations correctly
|
||||||
liveness.WriteFuncMap(fn, abiInfo)
|
liveness.WriteFuncMap(fn, abiInfo)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -209,12 +209,15 @@ func InitConfig() {
|
||||||
ir.Syms.SigPanic = typecheck.LookupRuntimeFunc("sigpanic")
|
ir.Syms.SigPanic = typecheck.LookupRuntimeFunc("sigpanic")
|
||||||
}
|
}
|
||||||
|
|
||||||
// AbiForFunc returns the ABI for a function, used to figure out arg/result mapping for rtcall and bodyless functions.
|
// AbiForBodylessFuncStackMap returns the ABI for a bodyless function's stack map.
|
||||||
// This follows policy for GOEXPERIMENT=regabi, //go:registerparams, and currently defined ABIInternal.
|
// This is not necessarily the ABI used to call it.
|
||||||
// Policy is subject to change....
|
// Currently (1.17 dev) such a stack map is always ABI0;
|
||||||
|
// any ABI wrapper that is present is nosplit, hence a precise
|
||||||
|
// stack map is not needed there (the parameters survive only long
|
||||||
|
// enough to call the wrapped assembly function).
|
||||||
// This always returns a freshly copied ABI.
|
// This always returns a freshly copied ABI.
|
||||||
func AbiForFunc(fn *ir.Func) *abi.ABIConfig {
|
func AbiForBodylessFuncStackMap(fn *ir.Func) *abi.ABIConfig {
|
||||||
return abiForFunc(fn, ssaConfig.ABI0, ssaConfig.ABI1).Copy() // No idea what races will result, be safe
|
return ssaConfig.ABI0.Copy() // No idea what races will result, be safe
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO (NLT 2021-04-15) This must be changed to a name that cannot match; it may be helpful to other register ABI work to keep the trigger-logic
|
// TODO (NLT 2021-04-15) This must be changed to a name that cannot match; it may be helpful to other register ABI work to keep the trigger-logic
|
||||||
|
|
@ -4839,24 +4842,24 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
||||||
var codeptr *ssa.Value // ptr to target code (if dynamic)
|
var codeptr *ssa.Value // ptr to target code (if dynamic)
|
||||||
var rcvr *ssa.Value // receiver to set
|
var rcvr *ssa.Value // receiver to set
|
||||||
fn := n.X
|
fn := n.X
|
||||||
var ACArgs []*types.Type // AuxCall args
|
var ACArgs []*types.Type // AuxCall args
|
||||||
var ACResults []*types.Type // AuxCall results
|
var ACResults []*types.Type // AuxCall results
|
||||||
var callArgs []*ssa.Value // For late-expansion, the args themselves (not stored, args to the call instead).
|
var callArgs []*ssa.Value // For late-expansion, the args themselves (not stored, args to the call instead).
|
||||||
inRegisters := false
|
inRegistersForTesting := false // If a call uses register ABI for one of the testing reasons, pragma, magic types, magic names
|
||||||
|
|
||||||
var magicFnNameSym *types.Sym
|
var magicFnNameSym *types.Sym
|
||||||
if fn.Name() != nil {
|
if fn.Name() != nil {
|
||||||
magicFnNameSym = fn.Name().Sym()
|
magicFnNameSym = fn.Name().Sym()
|
||||||
ss := magicFnNameSym.Name
|
ss := magicFnNameSym.Name
|
||||||
if strings.HasSuffix(ss, magicNameDotSuffix) {
|
if strings.HasSuffix(ss, magicNameDotSuffix) {
|
||||||
inRegisters = true
|
inRegistersForTesting = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if magicFnNameSym == nil && n.Op() == ir.OCALLINTER {
|
if magicFnNameSym == nil && n.Op() == ir.OCALLINTER {
|
||||||
magicFnNameSym = fn.(*ir.SelectorExpr).Sym()
|
magicFnNameSym = fn.(*ir.SelectorExpr).Sym()
|
||||||
ss := magicFnNameSym.Name
|
ss := magicFnNameSym.Name
|
||||||
if strings.HasSuffix(ss, magicNameDotSuffix[1:]) {
|
if strings.HasSuffix(ss, magicNameDotSuffix[1:]) {
|
||||||
inRegisters = true
|
inRegistersForTesting = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4872,7 +4875,7 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
||||||
// TODO(register args) remove after register abi is working
|
// TODO(register args) remove after register abi is working
|
||||||
inRegistersImported := fn.Pragma()&ir.RegisterParams != 0
|
inRegistersImported := fn.Pragma()&ir.RegisterParams != 0
|
||||||
inRegistersSamePackage := fn.Func != nil && fn.Func.Pragma&ir.RegisterParams != 0
|
inRegistersSamePackage := fn.Func != nil && fn.Func.Pragma&ir.RegisterParams != 0
|
||||||
inRegisters = inRegisters || inRegistersImported || inRegistersSamePackage
|
inRegistersForTesting = inRegistersForTesting || inRegistersImported || inRegistersSamePackage
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
closure = s.expr(fn)
|
closure = s.expr(fn)
|
||||||
|
|
@ -4898,13 +4901,13 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
||||||
}
|
}
|
||||||
|
|
||||||
if regAbiForFuncType(n.X.Type().FuncType()) {
|
if regAbiForFuncType(n.X.Type().FuncType()) {
|
||||||
// fmt.Printf("Saw magic last type in call %v\n", n)
|
// Magic last type in input args to call
|
||||||
inRegisters = true
|
inRegistersForTesting = true
|
||||||
}
|
}
|
||||||
|
|
||||||
callABI := s.f.ABI1
|
callABI := s.f.ABIDefault
|
||||||
if !inRegisters {
|
if inRegistersForTesting {
|
||||||
callABI = s.f.ABI0
|
callABI = s.f.ABI1
|
||||||
}
|
}
|
||||||
|
|
||||||
params := callABI.ABIAnalyze(n.X.Type(), false /* Do not set (register) nNames from caller side -- can cause races. */)
|
params := callABI.ABIAnalyze(n.X.Type(), false /* Do not set (register) nNames from caller side -- can cause races. */)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue