From: David Chase Date: Wed, 17 Feb 2021 23:01:52 +0000 (-0500) Subject: cmd/compile: pass arguments as register parameters to StaticCall. X-Git-Tag: go1.17beta1~1298 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=95ff296a11606cec32fb697c74aee520f23498b0;p=gostls13.git cmd/compile: pass arguments as register parameters to StaticCall. Additional register-parameter plumbing, not all the way to the end; if you test register parameter-passing, it fails mid-compilation. For #40724. Change-Id: Ibb675022c9156779a451726329890e52fca1cb33 Reviewed-on: https://go-review.googlesource.com/c/go/+/293398 Trust: David Chase Run-TryBot: David Chase Reviewed-by: Cherry Zhang Reviewed-by: Jeremy Faller --- diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go index 1868e3f073..ff16eac90f 100644 --- a/src/cmd/compile/internal/ssa/expand_calls.go +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -806,7 +806,6 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value, s := mem if storeRc.hasRegs() { - // TODO(register args) storeRc.addArg(source) } else { dst := x.offsetFrom(storeRc.storeDest, offset, types.NewPtr(t)) @@ -821,21 +820,15 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value, // rewriteArgs removes all the Args from a call and converts the call args into appropriate // stores (or later, register movement). Extra args for interface and closure calls are ignored, // but removed. -func (x *expandState) rewriteArgs(v *Value, firstArg int) *Value { +func (x *expandState) rewriteArgs(v *Value, firstArg int) (*Value, []*Value) { // Thread the stores on the memory arg aux := v.Aux.(*AuxCall) pos := v.Pos.WithNotStmt() m0 := v.MemoryArg() mem := m0 allResults := []*Value{} - for i, a := range v.Args { - if i < firstArg { - continue - } - if a == m0 { // mem is last. - break - } - auxI := int64(i - firstArg) + for i, a := range v.Args[firstArg : len(v.Args)-1] { // skip leading non-parameter SSA Args and trailing mem SSA Arg. + auxI := int64(i) aRegs := aux.RegsOfArg(auxI) aType := aux.TypeOfArg(auxI) if a.Op == OpDereference { @@ -863,11 +856,10 @@ func (x *expandState) rewriteArgs(v *Value, firstArg int) *Value { } rc.init(aRegs, aux.abiInfo, result, x.sp) mem = x.storeArgOrLoad(pos, v.Block, a, mem, aType, aOffset, 0, rc) - // TODO append mem to Result, update type } } v.resetArgs() - return mem + return mem, allResults } // expandCalls converts LE (Late Expansion) calls that act like they receive value args into a lower-level form @@ -921,17 +913,30 @@ func expandCalls(f *Func) { for _, v := range b.Values { switch v.Op { case OpStaticLECall: - mem := x.rewriteArgs(v, 0) - v.SetArgs1(mem) + mem, results := x.rewriteArgs(v, 0) + v.AddArgs(results...) + v.AddArg(mem) case OpClosureLECall: code := v.Args[0] context := v.Args[1] - mem := x.rewriteArgs(v, 2) - v.SetArgs3(code, context, mem) + mem, results := x.rewriteArgs(v, 2) + if len(results) == 0 { + v.SetArgs3(code, context, mem) + } else { + v.SetArgs2(code, context) + v.AddArgs(results...) + v.AddArg(mem) + } case OpInterLECall: code := v.Args[0] - mem := x.rewriteArgs(v, 1) - v.SetArgs2(code, mem) + mem, results := x.rewriteArgs(v, 1) + if len(results) == 0 { + v.SetArgs2(code, mem) + } else { + v.SetArgs1(code) + v.AddArgs(results...) + v.AddArg(mem) + } } } if isBlockMultiValueExit(b) { @@ -942,11 +947,8 @@ func expandCalls(f *Func) { aux := f.OwnAux pos := v.Pos.WithNotStmt() allResults := []*Value{} - for j, a := range v.Args { + for j, a := range v.Args[:len(v.Args)-1] { i := int64(j) - if a == m0 { - break - } auxType := aux.TypeOfResult(i) auxBase := b.NewValue2A(v.Pos, OpLocalAddr, types.NewPtr(auxType), aux.results[i].Name, x.sp, mem) auxOffset := int64(0) @@ -978,11 +980,10 @@ func expandCalls(f *Func) { result = &allResults } rc.init(aRegs, aux.abiInfo, result, auxBase) - // TODO REGISTER mem = x.storeArgOrLoad(v.Pos, b, a, mem, aux.TypeOfResult(i), auxOffset, 0, rc) - // TODO append mem to Result, update type } } + // TODO REGISTER -- keep the Result for block control, splice in contents of AllResults b.SetControl(mem) v.reset(OpInvalid) // otherwise it can have a mem operand which will fail check(), even though it is dead. }