diff options
author | David Chase <drchase@google.com> | 2021-04-21 10:55:42 -0400 |
---|---|---|
committer | David Chase <drchase@google.com> | 2021-05-08 17:03:18 +0000 |
commit | b38b1b2f9ae710ee2c16a103bb21644f1adbc5d3 (patch) | |
tree | 49395dd78b327b3f7e4d22d3c0229763de12ca39 /src/cmd/compile/internal/ssa/expand_calls.go | |
parent | 68327e1aa11457cd570bc7eaf03a0260950f27d9 (diff) | |
download | go-b38b1b2f9ae710ee2c16a103bb21644f1adbc5d3.tar.gz go-b38b1b2f9ae710ee2c16a103bb21644f1adbc5d3.zip |
cmd/compile: manage Slot array better
steals idea from CL 312093
further investigation revealed additional duplicate
slots (equivalent, but not equal), so delete those too.
Rearranged Func.Names to be addresses of slots,
create canonical addresses so that split slots
(which use those addresses to refer to their parent,
and split slots can be further split)
will preserve "equivalent slots are equal".
Removes duplicates, improves metrics for "args at entry".
Change-Id: I5bbdcb50bd33655abcab3d27ad8cdce25499faaf
Reviewed-on: https://go-review.googlesource.com/c/go/+/312292
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <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 | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go index 2852753bee..d37d06f8e7 100644 --- a/src/cmd/compile/internal/ssa/expand_calls.go +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -243,10 +243,10 @@ func (x *expandState) offsetFrom(b *Block, from *Value, offset int64, pt *types. } // splitSlots splits one "field" (specified by sfx, offset, and ty) out of the LocalSlots in ls and returns the new LocalSlots this generates. -func (x *expandState) splitSlots(ls []LocalSlot, sfx string, offset int64, ty *types.Type) []LocalSlot { - var locs []LocalSlot +func (x *expandState) splitSlots(ls []*LocalSlot, sfx string, offset int64, ty *types.Type) []*LocalSlot { + var locs []*LocalSlot for i := range ls { - locs = append(locs, x.f.fe.SplitSlot(&ls[i], sfx, offset, ty)) + locs = append(locs, x.f.SplitSlot(ls[i], sfx, offset, ty)) } return locs } @@ -301,13 +301,13 @@ func (x *expandState) Printf(format string, a ...interface{}) (n int, err error) // It emits the code necessary to implement the leaf select operation that leads to the root. // // TODO when registers really arrive, must also decompose anything split across two registers or registers and memory. -func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, regOffset Abi1RO) []LocalSlot { +func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, regOffset Abi1RO) []*LocalSlot { if x.debug { x.indent(3) defer x.indent(-3) x.Printf("rewriteSelect(%s; %s; memOff=%d; regOff=%d)\n", leaf.LongString(), selector.LongString(), offset, regOffset) } - var locs []LocalSlot + var locs []*LocalSlot leafType := leaf.Type if len(selector.Args) > 0 { w := selector.Args[0] @@ -477,7 +477,7 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, case OpStructSelect: w := selector.Args[0] - var ls []LocalSlot + var ls []*LocalSlot if w.Type.Kind() != types.TSTRUCT { // IData artifact ls = x.rewriteSelect(leaf, w, offset, regOffset) } else { @@ -485,7 +485,7 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, ls = x.rewriteSelect(leaf, w, offset+w.Type.FieldOff(fldi), regOffset+x.regOffset(w.Type, fldi)) if w.Op != OpIData { for _, l := range ls { - locs = append(locs, x.f.fe.SplitStruct(l, int(selector.AuxInt))) + locs = append(locs, x.f.SplitStruct(l, int(selector.AuxInt))) } } } @@ -662,7 +662,7 @@ outer: func (x *expandState) decomposeArg(pos src.XPos, b *Block, source, mem *Value, t *types.Type, storeOffset int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value { pa := x.prAssignForArg(source) - var locs []LocalSlot + var locs []*LocalSlot for _, s := range x.namedSelects[source] { locs = append(locs, x.f.Names[s.locIndex]) } @@ -756,12 +756,15 @@ func (x *expandState) decomposeArg(pos src.XPos, b *Block, source, mem *Value, t return nil } -func (x *expandState) splitSlotsIntoNames(locs []LocalSlot, suffix string, off int64, rt *types.Type, w *Value) { +func (x *expandState) splitSlotsIntoNames(locs []*LocalSlot, suffix string, off int64, rt *types.Type, w *Value) { wlocs := x.splitSlots(locs, suffix, off, rt) for _, l := range wlocs { - x.f.NamedValues[l] = append(x.f.NamedValues[l], w) + old, ok := x.f.NamedValues[*l] + x.f.NamedValues[*l] = append(old, w) + if !ok { + x.f.Names = append(x.f.Names, l) + } } - x.f.Names = append(x.f.Names, wlocs...) } // decomposeLoad is a helper for storeArgOrLoad. @@ -826,7 +829,7 @@ func (x *expandState) decomposeLoad(pos src.XPos, b *Block, source, mem *Value, // storeOneArg creates a decomposed (one step) arg that is then stored. // pos and b locate the store instruction, source is the "base" of the value input, // mem is the input mem, t is the type in question, and offArg and offStore are the offsets from the respective bases. -func storeOneArg(x *expandState, pos src.XPos, b *Block, locs []LocalSlot, suffix string, source, mem *Value, t *types.Type, argOffset, storeOffset int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value { +func storeOneArg(x *expandState, pos src.XPos, b *Block, locs []*LocalSlot, suffix string, source, mem *Value, t *types.Type, argOffset, storeOffset int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value { if x.debug { x.indent(3) defer x.indent(-3) @@ -848,7 +851,7 @@ func storeOneLoad(x *expandState, pos src.XPos, b *Block, source, mem *Value, t return x.storeArgOrLoad(pos, b, w, mem, t, offStore, loadRegOffset, storeRc) } -func storeTwoArg(x *expandState, pos src.XPos, b *Block, locs []LocalSlot, suffix1 string, suffix2 string, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value { +func storeTwoArg(x *expandState, pos src.XPos, b *Block, locs []*LocalSlot, suffix1 string, suffix2 string, source, mem *Value, t1, t2 *types.Type, offArg, offStore int64, loadRegOffset Abi1RO, storeRc registerCursor) *Value { mem = storeOneArg(x, pos, b, locs, suffix1, source, mem, t1, offArg, offStore, loadRegOffset, storeRc.next(t1)) pos = pos.WithNotStmt() t1Size := t1.Size() @@ -1168,7 +1171,7 @@ func expandCalls(f *Func) { for i, name := range f.Names { t := name.Type if x.isAlreadyExpandedAggregateType(t) { - for j, v := range f.NamedValues[name] { + for j, v := range f.NamedValues[*name] { if v.Op == OpSelectN || v.Op == OpArg && x.isAlreadyExpandedAggregateType(v.Type) { ns := x.namedSelects[v] x.namedSelects[v] = append(ns, namedVal{locIndex: i, valIndex: j}) @@ -1477,10 +1480,10 @@ func expandCalls(f *Func) { // Leaf types may have debug locations if !x.isAlreadyExpandedAggregateType(v.Type) { for _, l := range locs { - if _, ok := f.NamedValues[l]; !ok { + if _, ok := f.NamedValues[*l]; !ok { f.Names = append(f.Names, l) } - f.NamedValues[l] = append(f.NamedValues[l], v) + f.NamedValues[*l] = append(f.NamedValues[*l], v) } continue } @@ -1553,7 +1556,7 @@ func expandCalls(f *Func) { // Step 6: elide any copies introduced. // Update named values. for _, name := range f.Names { - values := f.NamedValues[name] + values := f.NamedValues[*name] for i, v := range values { if v.Op == OpCopy { a := v.Args[0] @@ -1725,7 +1728,8 @@ func (x *expandState) newArgToMemOrRegs(baseArg, toReplace *Value, offset int64, loc := LocalSlot{N: aux.Name, Type: t, Off: 0} values, ok := x.f.NamedValues[loc] if !ok { - x.f.Names = append(x.f.Names, loc) + ploc := x.f.localSlotAddr(loc) + x.f.Names = append(x.f.Names, ploc) } x.f.NamedValues[loc] = append(values, w) } |