Skip to content

Commit

Permalink
cmd/compile: separate ssa.Frontend and ssa.TypeSource
Browse files Browse the repository at this point in the history
Prior to this CL, the ssa.Frontend field was responsible
for providing types to the backend during compilation.
However, the types needed by the backend are few and static.
It makes more sense to use a struct for them
and to hang that struct off the ssa.Config,
which is the correct home for readonly data.
Now that Types is a struct, we can clean up the names a bit as well.

This has the added benefit of allowing early construction
of all types needed by the backend.
This will be useful for concurrent backend compilation.

Passes toolstash-check -all. No compiler performance change.

Updates #15756

Change-Id: I021658c8cf2836d6a22bbc20cc828ac38c7da08a
Reviewed-on: https://go-review.googlesource.com/38336
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
  • Loading branch information
josharian committed Mar 19, 2017
1 parent 2c397c7 commit aea3aff
Show file tree
Hide file tree
Showing 31 changed files with 4,674 additions and 4,634 deletions.
35 changes: 18 additions & 17 deletions src/cmd/compile/internal/gc/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,24 @@ var ssaConfig *ssa.Config
var ssaCache *ssa.Cache

func initssaconfig() {
ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, Ctxt, Debug['N'] == 0)
types := ssa.Types{
Bool: Types[TBOOL],
Int8: Types[TINT8],
Int16: Types[TINT16],
Int32: Types[TINT32],
Int64: Types[TINT64],
UInt8: Types[TUINT8],
UInt16: Types[TUINT16],
UInt32: Types[TUINT32],
UInt64: Types[TUINT64],
Float32: Types[TFLOAT32],
Float64: Types[TFLOAT64],
Int: Types[TINT],
Uintptr: Types[TUINTPTR],
String: Types[TSTRING],
BytePtr: ptrto(Types[TUINT8]),
}
ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, types, Ctxt, Debug['N'] == 0)
if thearch.LinkArch.Name == "386" {
ssaConfig.Set387(thearch.Use387)
}
Expand Down Expand Up @@ -4673,22 +4690,6 @@ type ssafn struct {
log bool
}

func (s *ssafn) TypeBool() ssa.Type { return Types[TBOOL] }
func (s *ssafn) TypeInt8() ssa.Type { return Types[TINT8] }
func (s *ssafn) TypeInt16() ssa.Type { return Types[TINT16] }
func (s *ssafn) TypeInt32() ssa.Type { return Types[TINT32] }
func (s *ssafn) TypeInt64() ssa.Type { return Types[TINT64] }
func (s *ssafn) TypeUInt8() ssa.Type { return Types[TUINT8] }
func (s *ssafn) TypeUInt16() ssa.Type { return Types[TUINT16] }
func (s *ssafn) TypeUInt32() ssa.Type { return Types[TUINT32] }
func (s *ssafn) TypeUInt64() ssa.Type { return Types[TUINT64] }
func (s *ssafn) TypeFloat32() ssa.Type { return Types[TFLOAT32] }
func (s *ssafn) TypeFloat64() ssa.Type { return Types[TFLOAT64] }
func (s *ssafn) TypeInt() ssa.Type { return Types[TINT] }
func (s *ssafn) TypeUintptr() ssa.Type { return Types[TUINTPTR] }
func (s *ssafn) TypeString() ssa.Type { return Types[TSTRING] }
func (s *ssafn) TypeBytePtr() ssa.Type { return ptrto(Types[TUINT8]) }

// StringData returns a symbol (a *Sym wrapped in an interface) which
// is the data component of a global string constant containing s.
func (*ssafn) StringData(s string) interface{} {
Expand Down
50 changes: 25 additions & 25 deletions src/cmd/compile/internal/ssa/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import (
// It is created once, early during compilation,
// and shared across all compilations.
type Config struct {
arch string // "amd64", etc.
IntSize int64 // 4 or 8
PtrSize int64 // 4 or 8
RegSize int64 // 4 or 8
arch string // "amd64", etc.
IntSize int64 // 4 or 8
PtrSize int64 // 4 or 8
RegSize int64 // 4 or 8
Types Types
lowerBlock blockRewriter // lowering function
lowerValue valueRewriter // lowering function
registers []Register // machine registers
Expand All @@ -44,24 +45,22 @@ type (
valueRewriter func(*Value) bool
)

type TypeSource interface {
TypeBool() Type
TypeInt8() Type
TypeInt16() Type
TypeInt32() Type
TypeInt64() Type
TypeUInt8() Type
TypeUInt16() Type
TypeUInt32() Type
TypeUInt64() Type
TypeInt() Type
TypeFloat32() Type
TypeFloat64() Type
TypeUintptr() Type
TypeString() Type
TypeBytePtr() Type // TODO: use unsafe.Pointer instead?

CanSSA(t Type) bool
type Types struct {
Bool Type
Int8 Type
Int16 Type
Int32 Type
Int64 Type
UInt8 Type
UInt16 Type
UInt32 Type
UInt64 Type
Int Type
Float32 Type
Float64 Type
Uintptr Type
String Type
BytePtr Type // TODO: use unsafe.Pointer instead?
}

type Logger interface {
Expand All @@ -87,7 +86,8 @@ type Logger interface {
}

type Frontend interface {
TypeSource
CanSSA(t Type) bool

Logger

// StringData returns a symbol pointing to the given string's contents.
Expand Down Expand Up @@ -135,8 +135,8 @@ type GCNode interface {
}

// NewConfig returns a new configuration object for the given architecture.
func NewConfig(arch string, ctxt *obj.Link, optimize bool) *Config {
c := &Config{arch: arch}
func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config {
c := &Config{arch: arch, Types: types}
switch arch {
case "amd64":
c.IntSize = 8
Expand Down
50 changes: 25 additions & 25 deletions src/cmd/compile/internal/ssa/decompose.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,25 @@ func decomposeBuiltIn(f *Func) {
case t.IsInteger() && t.Size() == 8 && f.Config.IntSize == 4:
var elemType Type
if t.IsSigned() {
elemType = f.fe.TypeInt32()
elemType = f.Config.Types.Int32
} else {
elemType = f.fe.TypeUInt32()
elemType = f.Config.Types.UInt32
}
hiName, loName := f.fe.SplitInt64(name)
newNames = append(newNames, hiName, loName)
for _, v := range f.NamedValues[name] {
hi := v.Block.NewValue1(v.Pos, OpInt64Hi, elemType, v)
lo := v.Block.NewValue1(v.Pos, OpInt64Lo, f.fe.TypeUInt32(), v)
lo := v.Block.NewValue1(v.Pos, OpInt64Lo, f.Config.Types.UInt32, v)
f.NamedValues[hiName] = append(f.NamedValues[hiName], hi)
f.NamedValues[loName] = append(f.NamedValues[loName], lo)
}
delete(f.NamedValues, name)
case t.IsComplex():
var elemType Type
if t.Size() == 16 {
elemType = f.fe.TypeFloat64()
elemType = f.Config.Types.Float64
} else {
elemType = f.fe.TypeFloat32()
elemType = f.Config.Types.Float32
}
rName, iName := f.fe.SplitComplex(name)
newNames = append(newNames, rName, iName)
Expand All @@ -58,8 +58,8 @@ func decomposeBuiltIn(f *Func) {
}
delete(f.NamedValues, name)
case t.IsString():
ptrType := f.fe.TypeBytePtr()
lenType := f.fe.TypeInt()
ptrType := f.Config.Types.BytePtr
lenType := f.Config.Types.Int
ptrName, lenName := f.fe.SplitString(name)
newNames = append(newNames, ptrName, lenName)
for _, v := range f.NamedValues[name] {
Expand All @@ -70,8 +70,8 @@ func decomposeBuiltIn(f *Func) {
}
delete(f.NamedValues, name)
case t.IsSlice():
ptrType := f.fe.TypeBytePtr()
lenType := f.fe.TypeInt()
ptrType := f.Config.Types.BytePtr
lenType := f.Config.Types.Int
ptrName, lenName, capName := f.fe.SplitSlice(name)
newNames = append(newNames, ptrName, lenName, capName)
for _, v := range f.NamedValues[name] {
Expand All @@ -84,7 +84,7 @@ func decomposeBuiltIn(f *Func) {
}
delete(f.NamedValues, name)
case t.IsInterface():
ptrType := f.fe.TypeBytePtr()
ptrType := f.Config.Types.BytePtr
typeName, dataName := f.fe.SplitInterface(name)
newNames = append(newNames, typeName, dataName)
for _, v := range f.NamedValues[name] {
Expand Down Expand Up @@ -129,9 +129,9 @@ func decomposeBuiltInPhi(v *Value) {
}

func decomposeStringPhi(v *Value) {
fe := v.Block.Func.fe
ptrType := fe.TypeBytePtr()
lenType := fe.TypeInt()
types := &v.Block.Func.Config.Types
ptrType := types.BytePtr
lenType := types.Int

ptr := v.Block.NewValue0(v.Pos, OpPhi, ptrType)
len := v.Block.NewValue0(v.Pos, OpPhi, lenType)
Expand All @@ -145,9 +145,9 @@ func decomposeStringPhi(v *Value) {
}

func decomposeSlicePhi(v *Value) {
fe := v.Block.Func.fe
ptrType := fe.TypeBytePtr()
lenType := fe.TypeInt()
types := &v.Block.Func.Config.Types
ptrType := types.BytePtr
lenType := types.Int

ptr := v.Block.NewValue0(v.Pos, OpPhi, ptrType)
len := v.Block.NewValue0(v.Pos, OpPhi, lenType)
Expand All @@ -164,33 +164,33 @@ func decomposeSlicePhi(v *Value) {
}

func decomposeInt64Phi(v *Value) {
fe := v.Block.Func.fe
types := &v.Block.Func.Config.Types
var partType Type
if v.Type.IsSigned() {
partType = fe.TypeInt32()
partType = types.Int32
} else {
partType = fe.TypeUInt32()
partType = types.UInt32
}

hi := v.Block.NewValue0(v.Pos, OpPhi, partType)
lo := v.Block.NewValue0(v.Pos, OpPhi, fe.TypeUInt32())
lo := v.Block.NewValue0(v.Pos, OpPhi, types.UInt32)
for _, a := range v.Args {
hi.AddArg(a.Block.NewValue1(v.Pos, OpInt64Hi, partType, a))
lo.AddArg(a.Block.NewValue1(v.Pos, OpInt64Lo, fe.TypeUInt32(), a))
lo.AddArg(a.Block.NewValue1(v.Pos, OpInt64Lo, types.UInt32, a))
}
v.reset(OpInt64Make)
v.AddArg(hi)
v.AddArg(lo)
}

func decomposeComplexPhi(v *Value) {
fe := v.Block.Func.fe
types := &v.Block.Func.Config.Types
var partType Type
switch z := v.Type.Size(); z {
case 8:
partType = fe.TypeFloat32()
partType = types.Float32
case 16:
partType = fe.TypeFloat64()
partType = types.Float64
default:
v.Fatalf("decomposeComplexPhi: bad complex size %d", z)
}
Expand All @@ -207,7 +207,7 @@ func decomposeComplexPhi(v *Value) {
}

func decomposeInterfacePhi(v *Value) {
ptrType := v.Block.Func.fe.TypeBytePtr()
ptrType := v.Block.Func.Config.Types.BytePtr

itab := v.Block.NewValue0(v.Pos, OpPhi, ptrType)
data := v.Block.NewValue0(v.Pos, OpPhi, ptrType)
Expand Down
53 changes: 28 additions & 25 deletions src/cmd/compile/internal/ssa/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ var Copyelim = copyelim
var TestCtxt = obj.Linknew(&x86.Linkamd64)

func testConfig(t testing.TB) *Config {
return NewConfig("amd64", TestCtxt, true)
return NewConfig("amd64", dummyTypes, TestCtxt, true)
}

func testConfigS390X(t testing.TB) *Config {
return NewConfig("s390x", obj.Linknew(&s390x.Links390x), true)
return NewConfig("s390x", dummyTypes, obj.Linknew(&s390x.Links390x), true)
}

// DummyFrontend is a test-only frontend.
Expand Down Expand Up @@ -52,27 +52,27 @@ func (DummyFrontend) Auto(t Type) GCNode {
return &DummyAuto{t: t, s: "aDummyAuto"}
}
func (d DummyFrontend) SplitString(s LocalSlot) (LocalSlot, LocalSlot) {
return LocalSlot{s.N, d.TypeBytePtr(), s.Off}, LocalSlot{s.N, d.TypeInt(), s.Off + 8}
return LocalSlot{s.N, dummyTypes.BytePtr, s.Off}, LocalSlot{s.N, dummyTypes.Int, s.Off + 8}
}
func (d DummyFrontend) SplitInterface(s LocalSlot) (LocalSlot, LocalSlot) {
return LocalSlot{s.N, d.TypeBytePtr(), s.Off}, LocalSlot{s.N, d.TypeBytePtr(), s.Off + 8}
return LocalSlot{s.N, dummyTypes.BytePtr, s.Off}, LocalSlot{s.N, dummyTypes.BytePtr, s.Off + 8}
}
func (d DummyFrontend) SplitSlice(s LocalSlot) (LocalSlot, LocalSlot, LocalSlot) {
return LocalSlot{s.N, s.Type.ElemType().PtrTo(), s.Off},
LocalSlot{s.N, d.TypeInt(), s.Off + 8},
LocalSlot{s.N, d.TypeInt(), s.Off + 16}
LocalSlot{s.N, dummyTypes.Int, s.Off + 8},
LocalSlot{s.N, dummyTypes.Int, s.Off + 16}
}
func (d DummyFrontend) SplitComplex(s LocalSlot) (LocalSlot, LocalSlot) {
if s.Type.Size() == 16 {
return LocalSlot{s.N, d.TypeFloat64(), s.Off}, LocalSlot{s.N, d.TypeFloat64(), s.Off + 8}
return LocalSlot{s.N, dummyTypes.Float64, s.Off}, LocalSlot{s.N, dummyTypes.Float64, s.Off + 8}
}
return LocalSlot{s.N, d.TypeFloat32(), s.Off}, LocalSlot{s.N, d.TypeFloat32(), s.Off + 4}
return LocalSlot{s.N, dummyTypes.Float32, s.Off}, LocalSlot{s.N, dummyTypes.Float32, s.Off + 4}
}
func (d DummyFrontend) SplitInt64(s LocalSlot) (LocalSlot, LocalSlot) {
if s.Type.IsSigned() {
return LocalSlot{s.N, d.TypeInt32(), s.Off + 4}, LocalSlot{s.N, d.TypeUInt32(), s.Off}
return LocalSlot{s.N, dummyTypes.Int32, s.Off + 4}, LocalSlot{s.N, dummyTypes.UInt32, s.Off}
}
return LocalSlot{s.N, d.TypeUInt32(), s.Off + 4}, LocalSlot{s.N, d.TypeUInt32(), s.Off}
return LocalSlot{s.N, dummyTypes.UInt32, s.Off + 4}, LocalSlot{s.N, dummyTypes.UInt32, s.Off}
}
func (d DummyFrontend) SplitStruct(s LocalSlot, i int) LocalSlot {
return LocalSlot{s.N, s.Type.FieldType(i), s.Off + s.Type.FieldOff(i)}
Expand Down Expand Up @@ -101,21 +101,24 @@ func (d DummyFrontend) Warnl(_ src.XPos, msg string, args ...interface{}) { d.t
func (d DummyFrontend) Debug_checknil() bool { return false }
func (d DummyFrontend) Debug_wb() bool { return false }

func (d DummyFrontend) TypeBool() Type { return TypeBool }
func (d DummyFrontend) TypeInt8() Type { return TypeInt8 }
func (d DummyFrontend) TypeInt16() Type { return TypeInt16 }
func (d DummyFrontend) TypeInt32() Type { return TypeInt32 }
func (d DummyFrontend) TypeInt64() Type { return TypeInt64 }
func (d DummyFrontend) TypeUInt8() Type { return TypeUInt8 }
func (d DummyFrontend) TypeUInt16() Type { return TypeUInt16 }
func (d DummyFrontend) TypeUInt32() Type { return TypeUInt32 }
func (d DummyFrontend) TypeUInt64() Type { return TypeUInt64 }
func (d DummyFrontend) TypeFloat32() Type { return TypeFloat32 }
func (d DummyFrontend) TypeFloat64() Type { return TypeFloat64 }
func (d DummyFrontend) TypeInt() Type { return TypeInt64 }
func (d DummyFrontend) TypeUintptr() Type { return TypeUInt64 }
func (d DummyFrontend) TypeString() Type { panic("unimplemented") }
func (d DummyFrontend) TypeBytePtr() Type { return TypeBytePtr }
var dummyTypes = Types{
Bool: TypeBool,
Int8: TypeInt8,
Int16: TypeInt16,
Int32: TypeInt32,
Int64: TypeInt64,
UInt8: TypeUInt8,
UInt16: TypeUInt16,
UInt32: TypeUInt32,
UInt64: TypeUInt64,
Float32: TypeFloat32,
Float64: TypeFloat64,
Int: TypeInt64,
Uintptr: TypeUInt64,
String: nil,
BytePtr: TypeBytePtr,
}

func (d DummyFrontend) DerefItab(sym *obj.LSym, off int64) *obj.LSym { return nil }

func (d DummyFrontend) CanSSA(t Type) bool {
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/ssa/gen/386.rules
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@
(Neg32 x) -> (NEGL x)
(Neg16 x) -> (NEGL x)
(Neg8 x) -> (NEGL x)
(Neg32F x) && !config.use387 -> (PXOR x (MOVSSconst <fe.TypeFloat32()> [f2i(math.Copysign(0, -1))]))
(Neg64F x) && !config.use387 -> (PXOR x (MOVSDconst <fe.TypeFloat64()> [f2i(math.Copysign(0, -1))]))
(Neg32F x) && !config.use387 -> (PXOR x (MOVSSconst <types.Float32> [f2i(math.Copysign(0, -1))]))
(Neg64F x) && !config.use387 -> (PXOR x (MOVSDconst <types.Float64> [f2i(math.Copysign(0, -1))]))
(Neg32F x) && config.use387 -> (FCHS x)
(Neg64F x) && config.use387 -> (FCHS x)

Expand Down
Loading

0 comments on commit aea3aff

Please sign in to comment.