diff options
author | Keith Randall <khr@golang.org> | 2016-10-30 21:10:03 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2016-10-31 19:44:19 +0000 |
commit | 741445068f7f582824f1c5625159e0b728090265 (patch) | |
tree | f31cea51647013761ae19e6948370de586208a7e /src/cmd/compile/internal/ssa/decompose.go | |
parent | 9c066bab643a0224decdd71813096e0d1df0624c (diff) | |
download | go-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.go | 46 |
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 |