mirror of
https://github.com/golang/go
synced 2024-11-18 01:24:49 -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 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).
|
||||||
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
|
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) {
|
||||||
inRegistersForTesting = true
|
callABI = s.f.ABI1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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:]) {
|
||||||
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 {
|
if k == callNormal && fn.Op() == ir.ONAME && fn.(*ir.Name).Class == ir.PFUNC {
|
||||||
fn := fn.(*ir.Name)
|
fn := fn.(*ir.Name)
|
||||||
callee = fn
|
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
|
// 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
|
||||||
inRegistersForTesting = inRegistersForTesting || inRegistersImported || inRegistersSamePackage
|
if inRegistersImported || inRegistersSamePackage {
|
||||||
|
callABI = s.f.ABI1
|
||||||
|
}
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
closure = s.expr(fn)
|
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()) {
|
if regAbiForFuncType(n.X.Type().FuncType()) {
|
||||||
// Magic last type in input args to call
|
// Magic last type in input args to call
|
||||||
inRegistersForTesting = true
|
|
||||||
}
|
|
||||||
|
|
||||||
callABI := s.f.ABIDefault
|
|
||||||
if inRegistersForTesting {
|
|
||||||
callABI = s.f.ABI1
|
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. */)
|
||||||
types.CalcSize(fn.Type())
|
types.CalcSize(fn.Type())
|
||||||
|
Loading…
Reference in New Issue
Block a user