go/src/cmd/compile/internal/ssa/decompose.go
Keith Randall c24681ae2e [dev.ssa] cmd/compile: remember names of values
For debugging, spill values to named variables instead of autotmp_
variables if possible.  We do this by keeping a name -> value map
for each function, keep it up-to-date during deadcode elim, and use
it to override spill decisions in stackalloc.

It might even make stack frames a bit smaller, as it makes it easy
to identify a set of spills which are likely not to interfere.

This just works for one-word variables for now.  Strings/slices
will be a separate CL.

Change-Id: Ie89eba8cab16bcd41b311c479ec46dd7e64cdb67
Reviewed-on: https://go-review.googlesource.com/16336
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2015-10-28 17:00:31 +00:00

121 lines
3.1 KiB
Go

// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ssa
// decompose converts phi ops on compound types into phi
// ops on simple types.
// (The remaining compound ops are decomposed with rewrite rules.)
func decompose(f *Func) {
for _, b := range f.Blocks {
for _, v := range b.Values {
if v.Op != OpPhi {
continue
}
switch {
case v.Type.IsComplex():
decomposeComplexPhi(v)
case v.Type.IsString():
decomposeStringPhi(v)
case v.Type.IsSlice():
decomposeSlicePhi(v)
case v.Type.IsInterface():
decomposeInterfacePhi(v)
//case v.Type.IsStruct():
// decomposeStructPhi(v)
case v.Type.Size() > f.Config.IntSize:
f.Unimplementedf("undecomposed type %s", v.Type)
}
}
}
// TODO: decompose complex?
// TODO: decompose 64-bit ops on 32-bit archs?
}
func decomposeStringPhi(v *Value) {
fe := v.Block.Func.Config.fe
ptrType := fe.TypeBytePtr()
lenType := fe.TypeInt()
ptr := v.Block.NewValue0(v.Line, OpPhi, ptrType)
len := v.Block.NewValue0(v.Line, OpPhi, lenType)
for _, a := range v.Args {
ptr.AddArg(a.Block.NewValue1(v.Line, OpStringPtr, ptrType, a))
len.AddArg(a.Block.NewValue1(v.Line, OpStringLen, lenType, a))
}
v.Op = OpStringMake
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
v.AddArg(ptr)
v.AddArg(len)
}
func decomposeSlicePhi(v *Value) {
fe := v.Block.Func.Config.fe
ptrType := fe.TypeBytePtr()
lenType := fe.TypeInt()
ptr := v.Block.NewValue0(v.Line, OpPhi, ptrType)
len := v.Block.NewValue0(v.Line, OpPhi, lenType)
cap := v.Block.NewValue0(v.Line, OpPhi, lenType)
for _, a := range v.Args {
ptr.AddArg(a.Block.NewValue1(v.Line, OpSlicePtr, ptrType, a))
len.AddArg(a.Block.NewValue1(v.Line, OpSliceLen, lenType, a))
cap.AddArg(a.Block.NewValue1(v.Line, OpSliceCap, lenType, a))
}
v.Op = OpSliceMake
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
v.AddArg(ptr)
v.AddArg(len)
v.AddArg(cap)
}
func decomposeComplexPhi(v *Value) {
fe := v.Block.Func.Config.fe
var partType Type
switch z := v.Type.Size(); z {
case 8:
partType = fe.TypeFloat32()
case 16:
partType = fe.TypeFloat64()
default:
v.Fatalf("decomposeComplexPhi: bad complex size %d", z)
}
real := v.Block.NewValue0(v.Line, OpPhi, partType)
imag := v.Block.NewValue0(v.Line, OpPhi, partType)
for _, a := range v.Args {
real.AddArg(a.Block.NewValue1(v.Line, OpComplexReal, partType, a))
imag.AddArg(a.Block.NewValue1(v.Line, OpComplexImag, partType, a))
}
v.Op = OpComplexMake
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
v.AddArg(real)
v.AddArg(imag)
}
func decomposeInterfacePhi(v *Value) {
ptrType := v.Block.Func.Config.fe.TypeBytePtr()
itab := v.Block.NewValue0(v.Line, OpPhi, ptrType)
data := v.Block.NewValue0(v.Line, OpPhi, ptrType)
for _, a := range v.Args {
itab.AddArg(a.Block.NewValue1(v.Line, OpITab, ptrType, a))
data.AddArg(a.Block.NewValue1(v.Line, OpIData, ptrType, a))
}
v.Op = OpIMake
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
v.AddArg(itab)
v.AddArg(data)
}
func decomposeStructPhi(v *Value) {
// TODO
}