From: Austin Clements Date: Wed, 31 Mar 2021 21:41:07 +0000 (-0400) Subject: cmd/compile: fix outgoing calls with GOEXPERIMENT=regabiargs X-Git-Tag: go1.17beta1~896 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1f29e69bad3673aa4f9d1c4d1016170b9ced634a;p=gostls13.git 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 Run-TryBot: Austin Clements TryBot-Result: Go Bot Reviewed-by: Than McIntosh Reviewed-by: Cherry Zhang --- diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go index aaea732057..9c1c493233 100644 --- a/src/cmd/compile/internal/ssagen/ssa.go +++ b/src/cmd/compile/internal/ssagen/ssa.go @@ -4851,24 +4851,27 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val var codeptr *ssa.Value // ptr to target code (if dynamic) var rcvr *ssa.Value // receiver to set fn := n.X - 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 + 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). - 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.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) { + 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 + if magicFnNameSym == nil && n.Op() == ir.OCALLINTER { + magicFnNameSym = fn.(*ir.SelectorExpr).Sym() + ss := magicFnNameSym.Name + if strings.HasSuffix(ss, magicNameDotSuffix[1:]) { + 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 - // 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 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 + if inRegistersImported || inRegistersSamePackage { + callABI = s.f.ABI1 + } + } break } closure = s.expr(fn) @@ -4909,14 +4925,11 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val } } - 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 + if !objabi.Experiment.RegabiArgs { + if regAbiForFuncType(n.X.Type().FuncType()) { + // Magic last type in input args to call + callABI = s.f.ABI1 + } } params := callABI.ABIAnalyze(n.X.Type(), false /* Do not set (register) nNames from caller side -- can cause races. */)