aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/stackalloc.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2015-11-02 08:10:26 -0800
committerKeith Randall <khr@golang.org>2015-11-03 17:29:40 +0000
commit02f4d0a130ba95d7a03418c3ef308d7d21b34af3 (patch)
tree215eb9851e2a439261fd40af792b5d17688cccf9 /src/cmd/compile/internal/ssa/stackalloc.go
parent582baae22a108e0b5f09da52c20f5ced83fe6084 (diff)
downloadgo-02f4d0a130ba95d7a03418c3ef308d7d21b34af3.tar.xz
[dev.ssa] cmd/compile: start arguments as spilled
Declare a function's arguments as having already been spilled so their use just requires a restore. Allow spill locations to be portions of larger objects the stack. Required to load portions of compound input arguments. Rename the memory input to InputMem. Use Arg for the pre-spilled argument values. Change-Id: I8fe2a03ffbba1022d98bfae2052b376b96d32dda Reviewed-on: https://go-review.googlesource.com/16536 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/stackalloc.go')
-rw-r--r--src/cmd/compile/internal/ssa/stackalloc.go34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/cmd/compile/internal/ssa/stackalloc.go b/src/cmd/compile/internal/ssa/stackalloc.go
index 793162a797..3eb5c3cf4a 100644
--- a/src/cmd/compile/internal/ssa/stackalloc.go
+++ b/src/cmd/compile/internal/ssa/stackalloc.go
@@ -44,6 +44,13 @@ func stackalloc(f *Func) {
}
case v.Op == OpLoadReg:
s.add(v.Args[0].ID)
+ case v.Op == OpArg:
+ // This is an input argument which is pre-spilled. It is kind of
+ // like a StoreReg, but we don't remove v.ID here because we want
+ // this value to appear live even before this point. Being live
+ // all the way to the start of the entry block prevents other
+ // values from being allocated to the same slot and clobbering
+ // the input value before we have a chance to load it.
}
}
}
@@ -51,7 +58,7 @@ func stackalloc(f *Func) {
// Build map from values to their names, if any.
// A value may be associated with more than one name (e.g. after
// the assignment i=j). This step picks one name per value arbitrarily.
- names := make([]GCNode, f.NumValues())
+ names := make([]LocalSlot, f.NumValues())
for _, name := range f.Names {
// Note: not "range f.NamedValues" above, because
// that would be nondeterministic.
@@ -74,9 +81,17 @@ func stackalloc(f *Func) {
}
}
+ // Allocate args to their assigned locations.
+ for _, v := range f.Entry.Values {
+ if v.Op != OpArg {
+ continue
+ }
+ f.setHome(v, LocalSlot{v.Aux.(GCNode), v.Type, v.AuxInt})
+ }
+
// For each type, we keep track of all the stack slots we
// have allocated for that type.
- locations := map[Type][]*LocalSlot{}
+ locations := map[Type][]LocalSlot{}
// Each time we assign a stack slot to a value v, we remember
// the slot we used via an index into locations[v.Type].
@@ -99,16 +114,16 @@ func stackalloc(f *Func) {
// If this is a named value, try to use the name as
// the spill location.
- var name GCNode
+ var name LocalSlot
if v.Op == OpStoreReg {
name = names[v.Args[0].ID]
} else {
name = names[v.ID]
}
- if name != nil && v.Type.Equal(name.Typ()) {
+ if name.N != nil && v.Type.Equal(name.Type) {
for _, id := range interfere[v.ID] {
h := f.getHome(id)
- if h != nil && h.(*LocalSlot).N == name {
+ if h != nil && h.(LocalSlot) == name {
// A variable can interfere with itself.
// It is rare, but but it can happen.
goto noname
@@ -118,17 +133,16 @@ func stackalloc(f *Func) {
for _, a := range v.Args {
for _, id := range interfere[a.ID] {
h := f.getHome(id)
- if h != nil && h.(*LocalSlot).N == name {
+ if h != nil && h.(LocalSlot) == name {
goto noname
}
}
}
}
- loc := &LocalSlot{name}
- f.setHome(v, loc)
+ f.setHome(v, name)
if v.Op == OpPhi {
for _, a := range v.Args {
- f.setHome(a, loc)
+ f.setHome(a, name)
}
}
continue
@@ -169,7 +183,7 @@ func stackalloc(f *Func) {
}
// If there is no unused stack slot, allocate a new one.
if i == len(locs) {
- locs = append(locs, &LocalSlot{f.Config.fe.Auto(v.Type)})
+ locs = append(locs, LocalSlot{N: f.Config.fe.Auto(v.Type), Type: v.Type, Off: 0})
locations[v.Type] = locs
}
// Use the stack variable at that index for v.