From 816cf06a08b4fa6c80ca16460dc3d0fba1806d23 Mon Sep 17 00:00:00 2001 From: Michael McLoughlin Date: Fri, 4 Jan 2019 20:00:22 -0800 Subject: [PATCH] pass: doc exported symbols (#9) --- pass/alloc.go | 6 ++++++ pass/pass.go | 12 ++++++++++++ pass/reg.go | 3 +++ 3 files changed, 21 insertions(+) diff --git a/pass/alloc.go b/pass/alloc.go index 9e653b0..c67a211 100644 --- a/pass/alloc.go +++ b/pass/alloc.go @@ -13,6 +13,7 @@ type edge struct { X, Y reg.Register } +// Allocator is a graph-coloring register allocator. type Allocator struct { registers []reg.Physical allocation reg.Allocation @@ -21,6 +22,7 @@ type Allocator struct { vidtopid map[reg.VID]reg.PID } +// NewAllocator builds an allocator for the given physical registers. func NewAllocator(rs []reg.Physical) (*Allocator, error) { if len(rs) == 0 { return nil, errors.New("no registers") @@ -33,6 +35,7 @@ func NewAllocator(rs []reg.Physical) (*Allocator, error) { }, nil } +// NewAllocatorForKind builds an allocator for the given kind of registers. func NewAllocatorForKind(k reg.Kind) (*Allocator, error) { f := reg.FamilyOfKind(k) if f == nil { @@ -41,12 +44,14 @@ func NewAllocatorForKind(k reg.Kind) (*Allocator, error) { return NewAllocator(f.Registers()) } +// AddInterferenceSet records that r interferes with every register in s. Convenience wrapper around AddInterference. func (a *Allocator) AddInterferenceSet(r reg.Register, s reg.Set) { for y := range s { a.AddInterference(r, y) } } +// AddInterference records that x and y must be assigned to non-conflicting physical registers. func (a *Allocator) AddInterference(x, y reg.Register) { a.Add(x) a.Add(y) @@ -65,6 +70,7 @@ func (a *Allocator) Add(r reg.Register) { a.possible[v] = a.possibleregisters(v) } +// Allocate allocates physical registers. func (a *Allocator) Allocate() (reg.Allocation, error) { for { if err := a.update(); err != nil { diff --git a/pass/pass.go b/pass/pass.go index 2cfc2da..beff2fe 100644 --- a/pass/pass.go +++ b/pass/pass.go @@ -1,3 +1,4 @@ +// Package pass implements processing passes on avo Files. package pass import ( @@ -7,6 +8,8 @@ import ( "github.com/mmcloughlin/avo/printer" ) +// Compile pass compiles an avo file. Upon successful completion the avo file +// may be printed to Go assembly. var Compile = Concat( FunctionPass(LabelTarget), FunctionPass(CFG), @@ -17,18 +20,24 @@ var Compile = Concat( Func(IncludeTextFlagHeader), ) +// Interface for a processing pass. type Interface interface { Execute(*avo.File) error } +// Func adapts a function to the pass Interface. type Func func(*avo.File) error +// Execute calls p. func (p Func) Execute(f *avo.File) error { return p(f) } +// FunctionPass is a convenience for implementing a full file pass with a +// function that operates on each avo Function independently. type FunctionPass func(*avo.Function) error +// Execute calls p on every function in the file. Exits on the first error. func (p FunctionPass) Execute(f *avo.File) error { for _, fn := range f.Functions() { if err := p(fn); err != nil { @@ -38,6 +47,7 @@ func (p FunctionPass) Execute(f *avo.File) error { return nil } +// Concat returns a pass that executes the given passes in order, stopping on the first error. func Concat(passes ...Interface) Interface { return Func(func(f *avo.File) error { for _, p := range passes { @@ -49,11 +59,13 @@ func Concat(passes ...Interface) Interface { }) } +// Output pass prints a file. type Output struct { Writer io.WriteCloser Printer printer.Printer } +// Execute prints f with the configured Printer and writes output to Writer. func (o *Output) Execute(f *avo.File) error { b, err := o.Printer.Print(f) if err != nil { diff --git a/pass/reg.go b/pass/reg.go index e7162e6..fb6e5b4 100644 --- a/pass/reg.go +++ b/pass/reg.go @@ -66,6 +66,7 @@ func Liveness(fn *avo.Function) error { return nil } +// AllocateRegisters performs register allocation. func AllocateRegisters(fn *avo.Function) error { // Populate allocators (one per kind). as := map[reg.Kind]*Allocator{} @@ -108,6 +109,7 @@ func AllocateRegisters(fn *avo.Function) error { return nil } +// BindRegisters applies the result of register allocation, replacing all virtual registers with their assigned physical registers. func BindRegisters(fn *avo.Function) error { for _, i := range fn.Instructions() { for idx := range i.Operands { @@ -117,6 +119,7 @@ func BindRegisters(fn *avo.Function) error { return nil } +// VerifyAllocation performs sanity checks following register allocation. func VerifyAllocation(fn *avo.Function) error { // All registers should be physical. for _, i := range fn.Instructions() {