2015-08-18 10:26:28 -07:00
|
|
|
// 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 {
|
2015-08-28 14:24:10 -04:00
|
|
|
case v.Type.IsComplex():
|
|
|
|
|
decomposeComplexPhi(v)
|
2015-08-18 10:26:28 -07:00
|
|
|
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.TypeUintptr()
|
|
|
|
|
|
|
|
|
|
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.TypeUintptr()
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-28 14:24:10 -04:00
|
|
|
func decomposeComplexPhi(v *Value) {
|
|
|
|
|
fe := v.Block.Func.Config.fe
|
|
|
|
|
var partType Type
|
2015-08-28 14:24:10 -04:00
|
|
|
switch z := v.Type.Size(); z {
|
|
|
|
|
case 8:
|
2015-08-28 14:24:10 -04:00
|
|
|
partType = fe.TypeFloat32()
|
2015-08-28 14:24:10 -04:00
|
|
|
case 16:
|
2015-08-28 14:24:10 -04:00
|
|
|
partType = fe.TypeFloat64()
|
2015-08-28 14:24:10 -04:00
|
|
|
default:
|
|
|
|
|
v.Fatalf("decomposeComplexPhi: bad complex size %d", z)
|
2015-08-28 14:24:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-18 10:26:28 -07:00
|
|
|
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
|
|
|
|
|
}
|