summaryrefslogtreecommitdiff
path: root/vendor/github.com/mmcloughlin/avo/pass/pass.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mmcloughlin/avo/pass/pass.go')
-rw-r--r--vendor/github.com/mmcloughlin/avo/pass/pass.go100
1 files changed, 100 insertions, 0 deletions
diff --git a/vendor/github.com/mmcloughlin/avo/pass/pass.go b/vendor/github.com/mmcloughlin/avo/pass/pass.go
new file mode 100644
index 0000000..62f37b1
--- /dev/null
+++ b/vendor/github.com/mmcloughlin/avo/pass/pass.go
@@ -0,0 +1,100 @@
+// Package pass implements processing passes on avo Files.
+package pass
+
+import (
+ "io"
+
+ "github.com/mmcloughlin/avo/ir"
+ "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(
+ Verify,
+ FunctionPass(PruneJumpToFollowingLabel),
+ FunctionPass(PruneDanglingLabels),
+ FunctionPass(LabelTarget),
+ FunctionPass(CFG),
+ InstructionPass(ZeroExtend32BitOutputs),
+ FunctionPass(Liveness),
+ FunctionPass(AllocateRegisters),
+ FunctionPass(BindRegisters),
+ FunctionPass(VerifyAllocation),
+ Func(IncludeTextFlagHeader),
+ FunctionPass(PruneSelfMoves),
+ FunctionPass(RequiredISAExtensions),
+)
+
+// Interface for a processing pass.
+type Interface interface {
+ Execute(*ir.File) error
+}
+
+// Func adapts a function to the pass Interface.
+type Func func(*ir.File) error
+
+// Execute calls p.
+func (p Func) Execute(f *ir.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(*ir.Function) error
+
+// Execute calls p on every function in the file. Exits on the first error.
+func (p FunctionPass) Execute(f *ir.File) error {
+ for _, fn := range f.Functions() {
+ if err := p(fn); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// InstructionPass is a convenience for implementing a full file pass with a
+// function that operates on each Instruction independently.
+type InstructionPass func(*ir.Instruction) error
+
+// Execute calls p on every instruction in the file. Exits on the first error.
+func (p InstructionPass) Execute(f *ir.File) error {
+ for _, fn := range f.Functions() {
+ for _, i := range fn.Instructions() {
+ if err := p(i); err != nil {
+ return err
+ }
+ }
+ }
+ 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 *ir.File) error {
+ for _, p := range passes {
+ if err := p.Execute(f); err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+}
+
+// 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 *ir.File) error {
+ b, err := o.Printer.Print(f)
+ if err != nil {
+ return err
+ }
+ if _, err = o.Writer.Write(b); err != nil {
+ return err
+ }
+ return o.Writer.Close()
+}