diff options
author | David Chase <drchase@google.com> | 2021-02-22 21:51:35 -0500 |
---|---|---|
committer | David Chase <drchase@google.com> | 2021-03-04 19:45:11 +0000 |
commit | 9d88a9e2bf89068238ed02a0c960e58f547bb102 (patch) | |
tree | 97b23a5d25fbd2f5fd3e3060b1d7b581b99c19f7 /src/cmd/compile/internal/ssa/expand_calls.go | |
parent | 2d30c94874c127d9028e29b77fadeb284c23e89a (diff) | |
download | go-9d88a9e2bf89068238ed02a0c960e58f547bb102.tar.gz go-9d88a9e2bf89068238ed02a0c960e58f547bb102.zip |
cmd/compile: implement simple register results
at least for ints and strings
includes simple test
For #40724.
Change-Id: Ib8484e5b957b08f961574a67cfd93d3d26551558
Reviewed-on: https://go-review.googlesource.com/c/go/+/295309
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/expand_calls.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/expand_calls.go | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go index ff16eac90f..6e14a90e79 100644 --- a/src/cmd/compile/internal/ssa/expand_calls.go +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -14,10 +14,10 @@ import ( ) type selKey struct { - from *Value - offset int64 - size int64 - typ *types.Type + from *Value // what is selected from + offsetOrIndex int64 // whatever is appropriate for the selector + size int64 + typ *types.Type } type offsetKey struct { @@ -372,6 +372,7 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, // if applied to Op-mumble-call, the Aux tells us which result, regOffset specifies offset within result. If a register, should rewrite to OpSelectN for new call. // TODO these may be duplicated. Should memoize. Intermediate selectors will go dead, no worries there. call := selector.Args[0] + call0 := call aux := call.Aux.(*AuxCall) which := selector.AuxInt if which == aux.NResults() { // mem is after the results. @@ -398,7 +399,6 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, leafType := removeTrivialWrapperTypes(leaf.Type) if x.canSSAType(leafType) { pt := types.NewPtr(leafType) - off := x.offsetFrom(x.sp, offset+aux.OffsetOfResult(which), pt) // Any selection right out of the arg area/registers has to be same Block as call, use call as mem input. if call.Op == OpStaticLECall { // TODO this is temporary until all calls are register-able // Create a "mem" for any loads that need to occur. @@ -413,15 +413,30 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, call = mem } } - if leaf.Block == call.Block { - leaf.reset(OpLoad) - leaf.SetArgs2(off, call) - leaf.Type = leafType + outParam := aux.abiInfo.OutParam(int(which)) + if len(outParam.Registers) > 0 { + reg := int64(outParam.Registers[regOffset]) + if leaf.Block == call.Block { + leaf.reset(OpSelectN) + leaf.SetArgs1(call0) + leaf.Type = leafType + leaf.AuxInt = reg + } else { + w := call.Block.NewValue1I(leaf.Pos, OpSelectN, leafType, reg, call0) + leaf.copyOf(w) + } } else { - w := call.Block.NewValue2(leaf.Pos, OpLoad, leafType, off, call) - leaf.copyOf(w) - if x.debug { - fmt.Printf("\tnew %s\n", w.LongString()) + off := x.offsetFrom(x.sp, offset+aux.OffsetOfResult(which), pt) + if leaf.Block == call.Block { + leaf.reset(OpLoad) + leaf.SetArgs2(off, call) + leaf.Type = leafType + } else { + w := call.Block.NewValue2(leaf.Pos, OpLoad, leafType, off, call) + leaf.copyOf(w) + if x.debug { + fmt.Printf("\tnew %s\n", w.LongString()) + } } } for _, s := range x.namedSelects[selector] { @@ -812,7 +827,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value, s = b.NewValue3A(pos, OpStore, types.TypeMem, t, dst, source, mem) } if x.debug { - fmt.Printf("\t\tstoreArg returns %s\n", s.LongString()) + fmt.Printf("\t\tstoreArg returns %s, storeRc=%s\n", s.LongString(), storeRc.String()) } return s } @@ -983,9 +998,11 @@ func expandCalls(f *Func) { mem = x.storeArgOrLoad(v.Pos, b, a, mem, aux.TypeOfResult(i), auxOffset, 0, rc) } } - // 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. + v.resetArgs() + v.AddArgs(allResults...) + v.AddArg(mem) + v.Type = types.NewResults(append(abi.RegisterTypes(aux.abiInfo.OutParams()), types.TypeMem)) + b.SetControl(v) } } @@ -1170,7 +1187,7 @@ func expandCalls(f *Func) { case OpArraySelect: offset = size * v.AuxInt case OpSelectN: - offset = w.Aux.(*AuxCall).OffsetOfResult(v.AuxInt) + offset = v.AuxInt // offset is just a key, really. case OpInt64Hi: offset = x.hiOffset case OpInt64Lo: @@ -1182,7 +1199,7 @@ func expandCalls(f *Func) { case OpComplexImag: offset = size } - sk := selKey{from: w, size: size, offset: offset, typ: typ} + sk := selKey{from: w, size: size, offsetOrIndex: offset, typ: typ} dupe := x.commonSelectors[sk] if dupe == nil { x.commonSelectors[sk] = v @@ -1240,8 +1257,9 @@ func expandCalls(f *Func) { x.rewriteArgToMemOrRegs(v) case OpStaticLECall: v.Op = OpStaticCall + rts := abi.RegisterTypes(v.Aux.(*AuxCall).abiInfo.OutParams()) // TODO need to insert all the register types. - v.Type = types.NewResults([]*types.Type{types.TypeMem}) + v.Type = types.NewResults(append(rts, types.TypeMem)) case OpClosureLECall: v.Op = OpClosureCall v.Type = types.TypeMem |