mirror of
https://github.com/golang/go
synced 2024-11-08 04:56: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
|
s := mem
|
||||||
if storeRc.hasRegs() {
|
if storeRc.hasRegs() {
|
||||||
// TODO(register args)
|
|
||||||
storeRc.addArg(source)
|
storeRc.addArg(source)
|
||||||
} else {
|
} else {
|
||||||
dst := x.offsetFrom(storeRc.storeDest, offset, types.NewPtr(t))
|
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
|
// 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,
|
// stores (or later, register movement). Extra args for interface and closure calls are ignored,
|
||||||
// but removed.
|
// 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
|
// Thread the stores on the memory arg
|
||||||
aux := v.Aux.(*AuxCall)
|
aux := v.Aux.(*AuxCall)
|
||||||
pos := v.Pos.WithNotStmt()
|
pos := v.Pos.WithNotStmt()
|
||||||
m0 := v.MemoryArg()
|
m0 := v.MemoryArg()
|
||||||
mem := m0
|
mem := m0
|
||||||
allResults := []*Value{}
|
allResults := []*Value{}
|
||||||
for i, a := range v.Args {
|
for i, a := range v.Args[firstArg : len(v.Args)-1] { // skip leading non-parameter SSA Args and trailing mem SSA Arg.
|
||||||
if i < firstArg {
|
auxI := int64(i)
|
||||||
continue
|
|
||||||
}
|
|
||||||
if a == m0 { // mem is last.
|
|
||||||
break
|
|
||||||
}
|
|
||||||
auxI := int64(i - firstArg)
|
|
||||||
aRegs := aux.RegsOfArg(auxI)
|
aRegs := aux.RegsOfArg(auxI)
|
||||||
aType := aux.TypeOfArg(auxI)
|
aType := aux.TypeOfArg(auxI)
|
||||||
if a.Op == OpDereference {
|
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)
|
rc.init(aRegs, aux.abiInfo, result, x.sp)
|
||||||
mem = x.storeArgOrLoad(pos, v.Block, a, mem, aType, aOffset, 0, rc)
|
mem = x.storeArgOrLoad(pos, v.Block, a, mem, aType, aOffset, 0, rc)
|
||||||
// TODO append mem to Result, update type
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v.resetArgs()
|
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
|
// 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 {
|
for _, v := range b.Values {
|
||||||
switch v.Op {
|
switch v.Op {
|
||||||
case OpStaticLECall:
|
case OpStaticLECall:
|
||||||
mem := x.rewriteArgs(v, 0)
|
mem, results := x.rewriteArgs(v, 0)
|
||||||
v.SetArgs1(mem)
|
v.AddArgs(results...)
|
||||||
|
v.AddArg(mem)
|
||||||
case OpClosureLECall:
|
case OpClosureLECall:
|
||||||
code := v.Args[0]
|
code := v.Args[0]
|
||||||
context := v.Args[1]
|
context := v.Args[1]
|
||||||
mem := x.rewriteArgs(v, 2)
|
mem, results := x.rewriteArgs(v, 2)
|
||||||
v.SetArgs3(code, context, mem)
|
if len(results) == 0 {
|
||||||
|
v.SetArgs3(code, context, mem)
|
||||||
|
} else {
|
||||||
|
v.SetArgs2(code, context)
|
||||||
|
v.AddArgs(results...)
|
||||||
|
v.AddArg(mem)
|
||||||
|
}
|
||||||
case OpInterLECall:
|
case OpInterLECall:
|
||||||
code := v.Args[0]
|
code := v.Args[0]
|
||||||
mem := x.rewriteArgs(v, 1)
|
mem, results := x.rewriteArgs(v, 1)
|
||||||
v.SetArgs2(code, mem)
|
if len(results) == 0 {
|
||||||
|
v.SetArgs2(code, mem)
|
||||||
|
} else {
|
||||||
|
v.SetArgs1(code)
|
||||||
|
v.AddArgs(results...)
|
||||||
|
v.AddArg(mem)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isBlockMultiValueExit(b) {
|
if isBlockMultiValueExit(b) {
|
||||||
@ -942,11 +947,8 @@ func expandCalls(f *Func) {
|
|||||||
aux := f.OwnAux
|
aux := f.OwnAux
|
||||||
pos := v.Pos.WithNotStmt()
|
pos := v.Pos.WithNotStmt()
|
||||||
allResults := []*Value{}
|
allResults := []*Value{}
|
||||||
for j, a := range v.Args {
|
for j, a := range v.Args[:len(v.Args)-1] {
|
||||||
i := int64(j)
|
i := int64(j)
|
||||||
if a == m0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
auxType := aux.TypeOfResult(i)
|
auxType := aux.TypeOfResult(i)
|
||||||
auxBase := b.NewValue2A(v.Pos, OpLocalAddr, types.NewPtr(auxType), aux.results[i].Name, x.sp, mem)
|
auxBase := b.NewValue2A(v.Pos, OpLocalAddr, types.NewPtr(auxType), aux.results[i].Name, x.sp, mem)
|
||||||
auxOffset := int64(0)
|
auxOffset := int64(0)
|
||||||
@ -978,11 +980,10 @@ func expandCalls(f *Func) {
|
|||||||
result = &allResults
|
result = &allResults
|
||||||
}
|
}
|
||||||
rc.init(aRegs, aux.abiInfo, result, auxBase)
|
rc.init(aRegs, aux.abiInfo, result, auxBase)
|
||||||
// TODO REGISTER
|
|
||||||
mem = x.storeArgOrLoad(v.Pos, b, a, mem, aux.TypeOfResult(i), auxOffset, 0, rc)
|
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)
|
b.SetControl(mem)
|
||||||
v.reset(OpInvalid) // otherwise it can have a mem operand which will fail check(), even though it is dead.
|
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