aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/expand_calls.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2021-04-21 10:55:42 -0400
committerDavid Chase <drchase@google.com>2021-05-08 17:03:18 +0000
commitb38b1b2f9ae710ee2c16a103bb21644f1adbc5d3 (patch)
tree49395dd78b327b3f7e4d22d3c0229763de12ca39 /src/cmd/compile/internal/ssa/expand_calls.go
parent68327e1aa11457cd570bc7eaf03a0260950f27d9 (diff)
downloadgo-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.go40
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)
}