mirror of
https://github.com/golang/go
synced 2024-11-17 23:04:56 -07:00
cmd/compile: fix outgoing calls with GOEXPERIMENT=regabiargs
The logic for constructing calls in (*state).call is based around targeted experiments with register-based calls. However, when the register ABI is turned on everywhere, it currently doesn't account for direct calls to non-ABIInternal functions. This CL adds a much simpler path to (*state).call when regabiargs is turned on that looks at the ABI of the target function. For #40724. Change-Id: I7f4f5fed8a5ec131bcf1ce5b9d94d45672a304cb Reviewed-on: https://go-review.googlesource.com/c/go/+/306410 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
3304b2235a
commit
1f29e69bad
@ -4854,21 +4854,24 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
||||
var ACArgs []*types.Type // AuxCall args
|
||||
var ACResults []*types.Type // AuxCall results
|
||||
var callArgs []*ssa.Value // For late-expansion, the args themselves (not stored, args to the call instead).
|
||||
inRegistersForTesting := false // If a call uses register ABI for one of the testing reasons, pragma, magic types, magic names
|
||||
|
||||
callABI := s.f.ABIDefault
|
||||
|
||||
if !objabi.Experiment.RegabiArgs {
|
||||
var magicFnNameSym *types.Sym
|
||||
if fn.Name() != nil {
|
||||
magicFnNameSym = fn.Name().Sym()
|
||||
ss := magicFnNameSym.Name
|
||||
if strings.HasSuffix(ss, magicNameDotSuffix) {
|
||||
inRegistersForTesting = true
|
||||
callABI = s.f.ABI1
|
||||
}
|
||||
}
|
||||
if magicFnNameSym == nil && n.Op() == ir.OCALLINTER {
|
||||
magicFnNameSym = fn.(*ir.SelectorExpr).Sym()
|
||||
ss := magicFnNameSym.Name
|
||||
if strings.HasSuffix(ss, magicNameDotSuffix[1:]) {
|
||||
inRegistersForTesting = true
|
||||
callABI = s.f.ABI1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4881,10 +4884,23 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
||||
if k == callNormal && fn.Op() == ir.ONAME && fn.(*ir.Name).Class == ir.PFUNC {
|
||||
fn := fn.(*ir.Name)
|
||||
callee = fn
|
||||
if objabi.Experiment.RegabiArgs {
|
||||
// This is a static call, so it may be
|
||||
// a direct call to a non-ABIInternal
|
||||
// function. fn.Func may be nil for
|
||||
// some compiler-generated functions,
|
||||
// but those are all ABIInternal.
|
||||
if fn.Func != nil {
|
||||
callABI = abiForFunc(fn.Func, s.f.ABI0, s.f.ABI1)
|
||||
}
|
||||
} else {
|
||||
// TODO(register args) remove after register abi is working
|
||||
inRegistersImported := fn.Pragma()&ir.RegisterParams != 0
|
||||
inRegistersSamePackage := fn.Func != nil && fn.Func.Pragma&ir.RegisterParams != 0
|
||||
inRegistersForTesting = inRegistersForTesting || inRegistersImported || inRegistersSamePackage
|
||||
if inRegistersImported || inRegistersSamePackage {
|
||||
callABI = s.f.ABI1
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
closure = s.expr(fn)
|
||||
@ -4909,15 +4925,12 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
||||
}
|
||||
}
|
||||
|
||||
if !objabi.Experiment.RegabiArgs {
|
||||
if regAbiForFuncType(n.X.Type().FuncType()) {
|
||||
// Magic last type in input args to call
|
||||
inRegistersForTesting = true
|
||||
}
|
||||
|
||||
callABI := s.f.ABIDefault
|
||||
if inRegistersForTesting {
|
||||
callABI = s.f.ABI1
|
||||
}
|
||||
}
|
||||
|
||||
params := callABI.ABIAnalyze(n.X.Type(), false /* Do not set (register) nNames from caller side -- can cause races. */)
|
||||
types.CalcSize(fn.Type())
|
||||
|
Loading…
Reference in New Issue
Block a user