aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/decompose.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2016-10-30 21:10:03 -0700
committerKeith Randall <khr@golang.org>2016-10-31 19:44:19 +0000
commit741445068f7f582824f1c5625159e0b728090265 (patch)
treef31cea51647013761ae19e6948370de586208a7e /src/cmd/compile/internal/ssa/decompose.go
parent9c066bab643a0224decdd71813096e0d1df0624c (diff)
downloadgo-741445068f7f582824f1c5625159e0b728090265.tar.gz
go-741445068f7f582824f1c5625159e0b728090265.zip
cmd/compile: make [0]T and [1]T SSAable types
We used to have to keep on-stack copies of these types. Now they can be registerized. [0]T is kind of trivial but might as well handle it. This change enables another change I'm working on to improve how x.(T) expressions are handled (#17405). This CL helps because now all types that are direct interface types are registerizeable (e.g. [1]*byte). No higher-degree arrays for now because non-constant indexes are hard. Update #17405 Change-Id: I2399940965d17b3969ae66f6fe447a8cefdd6edd Reviewed-on: https://go-review.googlesource.com/32416 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/decompose.go')
-rw-r--r--src/cmd/compile/internal/ssa/decompose.go46
1 files changed, 42 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go
index 04f45c1134..b2ee2f0a2b 100644
--- a/src/cmd/compile/internal/ssa/decompose.go
+++ b/src/cmd/compile/internal/ssa/decompose.go
@@ -253,6 +253,21 @@ func decomposeUser(f *Func) {
}
delete(f.NamedValues, name)
newNames = append(newNames, fnames...)
+ case t.IsArray():
+ if t.NumElem() == 0 {
+ // TODO(khr): Not sure what to do here. Probably nothing.
+ // Names for empty arrays aren't important.
+ break
+ }
+ if t.NumElem() != 1 {
+ f.Fatalf("array not of size 1")
+ }
+ elemName := f.Config.fe.SplitArray(name)
+ for _, v := range f.NamedValues[name] {
+ e := v.Block.NewValue1I(v.Line, OpArraySelect, t.ElemType(), 0, v)
+ f.NamedValues[elemName] = append(f.NamedValues[elemName], e)
+ }
+
default:
f.Names[i] = name
i++
@@ -266,10 +281,13 @@ func decomposeUserPhi(v *Value) {
switch {
case v.Type.IsStruct():
decomposeStructPhi(v)
+ case v.Type.IsArray():
+ decomposeArrayPhi(v)
}
- // TODO: Arrays of length 1?
}
+// decomposeStructPhi replaces phi-of-struct with structmake(phi-for-each-field),
+// and then recursively decomposes the phis for each field.
func decomposeStructPhi(v *Value) {
t := v.Type
n := t.NumFields()
@@ -287,10 +305,30 @@ func decomposeStructPhi(v *Value) {
// Recursively decompose phis for each field.
for _, f := range fields[:n] {
- if f.Type.IsStruct() {
- decomposeStructPhi(f)
- }
+ decomposeUserPhi(f)
+ }
+}
+
+// decomposeArrayPhi replaces phi-of-array with arraymake(phi-of-array-element),
+// and then recursively decomposes the element phi.
+func decomposeArrayPhi(v *Value) {
+ t := v.Type
+ if t.NumElem() == 0 {
+ v.reset(OpArrayMake0)
+ return
+ }
+ if t.NumElem() != 1 {
+ v.Fatalf("SSAable array must have no more than 1 element")
}
+ elem := v.Block.NewValue0(v.Line, OpPhi, t.ElemType())
+ for _, a := range v.Args {
+ elem.AddArg(a.Block.NewValue1I(v.Line, OpArraySelect, t.ElemType(), 0, a))
+ }
+ v.reset(OpArrayMake1)
+ v.AddArg(elem)
+
+ // Recursively decompose elem phi.
+ decomposeUserPhi(elem)
}
// MaxStruct is the maximum number of fields a struct