mirror of
https://github.com/golang/go
synced 2024-11-08 02:46:16 -07:00
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 <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
parent
04a4dca2ac
commit
95ff296a11
@ -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)
|
||||
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)
|
||||
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.
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user