aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/expand_calls.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2021-02-04 16:42:35 -0500
committerDavid Chase <drchase@google.com>2021-02-26 02:52:33 +0000
commite25040d16288563c89cead5e8da8d3b9c74ab655 (patch)
tree4e57425c9764cf01ac69447f06d1bb52f07d9e46 /src/cmd/compile/internal/ssa/expand_calls.go
parent9a555fc24c318bf1b07bdc07d5c02e372681e401 (diff)
downloadgo-e25040d16288563c89cead5e8da8d3b9c74ab655.tar.gz
go-e25040d16288563c89cead5e8da8d3b9c74ab655.zip
cmd/compile: change StaticCall to return a "Results"
StaticLECall (multiple value in +mem, multiple value result +mem) -> StaticCall (multiple ergister value in +mem, multiple register-sized-value result +mem) -> ARCH CallStatic (multiple ergister value in +mem, multiple register-sized-value result +mem) But the architecture-dependent stuff is indifferent to whether it is mem->mem or (mem)->(mem) until Prog generation. Deal with OpSelectN -> Prog in ssagen/ssa.go, others, as they appear. For #40724. Change-Id: I1d0436f6371054f1881862641d8e7e418e4a6a16 Reviewed-on: https://go-review.googlesource.com/c/go/+/293391 Trust: David Chase <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Go Bot <gobot@golang.org> 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.go38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 85d6fda427..292b0b41ce 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -170,6 +170,7 @@ type expandState struct {
sdom SparseTree
common map[selKey]*Value
offsets map[offsetKey]*Value
+ memForCall map[ID]*Value // For a call, need to know the unique selector that gets the mem.
}
// intPairTypes returns the pair of 32-bit int types needed to encode a 64-bit integer type on a target
@@ -280,7 +281,6 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64,
if !x.isAlreadyExpandedAggregateType(selector.Type) {
if leafType == selector.Type { // OpIData leads us here, sometimes.
leaf.copyOf(selector)
-
} else {
x.f.Fatalf("Unexpected OpArg type, selector=%s, leaf=%s\n", selector.LongString(), leaf.LongString())
}
@@ -357,13 +357,43 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64,
which := selector.AuxInt
if which == aux.NResults() { // mem is after the results.
// rewrite v as a Copy of call -- the replacement call will produce a mem.
- leaf.copyOf(call)
+ if call.Op == OpStaticLECall {
+ if leaf != selector {
+ panic("Unexpected selector of memory")
+ }
+ // StaticCall selector will address last element of Result.
+ // TODO do this for all the other call types eventually.
+ if aux.abiInfo == nil {
+ panic(fmt.Errorf("aux.abiInfo nil for call %s", call.LongString()))
+ }
+ if existing := x.memForCall[call.ID]; existing == nil {
+ selector.AuxInt = int64(aux.abiInfo.OutRegistersUsed())
+ x.memForCall[call.ID] = selector
+ } else {
+ selector.copyOf(existing)
+ }
+ } else {
+ leaf.copyOf(call)
+ }
} else {
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.
+ if mem := x.memForCall[call.ID]; mem != nil {
+ if mem.Block != call.Block {
+ panic(fmt.Errorf("selector and call need to be in same block, selector=%s; call=%s", selector.LongString(), call.LongString()))
+ }
+ call = mem
+ } else {
+ mem = call.Block.NewValue1I(call.Pos.WithNotStmt(), OpSelectN, types.TypeMem, int64(aux.abiInfo.OutRegistersUsed()), call)
+ x.memForCall[call.ID] = mem
+ call = mem
+ }
+ }
if leaf.Block == call.Block {
leaf.reset(OpLoad)
leaf.SetArgs2(off, call)
@@ -835,6 +865,7 @@ func expandCalls(f *Func) {
sdom: f.Sdom(),
common: make(map[selKey]*Value),
offsets: make(map[offsetKey]*Value),
+ memForCall: make(map[ID]*Value),
}
// For 32-bit, need to deal with decomposition of 64-bit integers, which depends on endianness.
@@ -1173,7 +1204,8 @@ func expandCalls(f *Func) {
switch v.Op {
case OpStaticLECall:
v.Op = OpStaticCall
- v.Type = types.TypeMem
+ // TODO need to insert all the register types.
+ v.Type = types.NewResults([]*types.Type{types.TypeMem})
case OpClosureLECall:
v.Op = OpClosureCall
v.Type = types.TypeMem