]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: pass arguments as register parameters to StaticCall.
authorDavid Chase <drchase@google.com>
Wed, 17 Feb 2021 23:01:52 +0000 (18:01 -0500)
committerDavid Chase <drchase@google.com>
Thu, 4 Mar 2021 03:29:58 +0000 (03:29 +0000)
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>
src/cmd/compile/internal/ssa/expand_calls.go

index 1868e3f073d9764aed35b7c89fde7ceadc79a15a..ff16eac90fe5b353553baffd846b0337c748542d 100644 (file)
@@ -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.
                }