codegen

package
v0.0.0-...-535c093 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2020 License: MIT Imports: 12 Imported by: 4

Documentation

Overview

Package codegen provides code generation of GoCaml language.

MIR compilation unit is compiled to an LLVM IR, an assembly, an object then finally linked to an executable. You can add many optimizations and debug information (DWARF).

Example
file := filepath.FromSlash("../testdata/from-mincaml/ack.ml")
src, err := locerr.NewSourceFromFile(file)
if err != nil {
	// File not found
	panic(err)
}

ast, err := syntax.Parse(src)
if err != nil {
	// When parse failed
	panic(err)
}

// Resolving symbols, type analysis and converting AST into MIR instruction block
env, block, err := sema.SemanticsCheck(ast)
if err != nil {
	// Type error detected
	panic(err)
}

// Create MIR compilation unit
program := closure.Transform(block)

// Make options to emit the result
options := EmitOptions{
	Optimization: OptimizeDefault,             // Optimization level
	Triple:       "x86_64-apple-darwin16.4.0", // Compilation target (Empty string means default target on your machine)
	DebugInfo:    true,                        // Add debug information to the result or not
}

// Emitter object, which compiles MIR to LLVM IR and emits assembly, object file or executable
// In factory function, given MIR code is already converted to LLVM IR
emitter, err := NewEmitter(program, env, src, options)
if err != nil {
	panic(err)
}

// You need to defer finalization
defer emitter.Dispose()

// Run LLVM IR level optimizations
emitter.RunOptimizationPasses()

// Show LLVM IR compiled from `program`
fmt.Println("LLVMIR:\n" + emitter.EmitLLVMIR())

// Emit platform-dependant assembly file
asm, err := emitter.EmitAsm()
if err != nil {
	panic(err)
}
fmt.Println("Assembly:\n" + asm)

// Emit object file contents as bytes (MIR -> LLVM IR -> object file)
object, err := emitter.EmitObject()
if err != nil {
	panic(err)
}
fmt.Printf("Object file:\n%v\n", object)

// Emit executable file as "a.out". This is the final result we want!
// It links the object file and runtime with a linker.
// (MIR -> LLVM IR -> assembly -> object -> executable)
if err := emitter.EmitExecutable("a.out"); err != nil {
	panic(err)
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type EmitOptions

type EmitOptions struct {
	// Optimization determines how many optimizations are added
	Optimization OptLevel
	// Triple represents target triple "{arch}-{vendor}-{sys}". Empty string means a default target
	// on your machine.
	// https://clang.llvm.org/docs/CrossCompilation.html#target-triple
	Triple string
	// Additional linker flags used at linking generated object files
	LinkerFlags string
	// DebugInfo determines to generate debug information or not. If true, debug information will
	// be added and you can debug the generated executable with debugger like an LLDB.
	DebugInfo bool
}

EmitOptions represents emitter options to customize emitter behavior

type Emitter

type Emitter struct {
	EmitOptions
	MIR      *mir.Program
	Env      *types.Env
	Source   *locerr.Source
	Module   llvm.Module
	Machine  llvm.TargetMachine
	Disposed bool
}

Emitter object to emit LLVM IR, object file, assembly or executable.

func NewEmitter

func NewEmitter(prog *mir.Program, env *types.Env, src *locerr.Source, opts EmitOptions) (*Emitter, error)

NewEmitter creates new emitter object.

func (*Emitter) Dispose

func (emitter *Emitter) Dispose()

Dispose does finalization for internal module and target machine. You need to call this with defer statement.

func (*Emitter) EmitAsm

func (emitter *Emitter) EmitAsm() (string, error)

EmitAsm returns assembly code as string.

func (*Emitter) EmitExecutable

func (emitter *Emitter) EmitExecutable(executable string) (err error)

EmitExecutable creates executable file with specified name. This is the final result of compilation!

func (*Emitter) EmitLLVMIR

func (emitter *Emitter) EmitLLVMIR() string

EmitLLVMIR returns LLVM IR as string.

func (*Emitter) EmitObject

func (emitter *Emitter) EmitObject() ([]byte, error)

EmitObject returns object file contents as byte sequence.

func (*Emitter) RunOptimizationPasses

func (emitter *Emitter) RunOptimizationPasses()

RunOptimizationPasses passes optimizations on generated LLVM IR module following specified optimization level.

type OptLevel

type OptLevel int
const (
	// OptimizeNone is equivalent to -O0
	OptimizeNone OptLevel = iota
	// OptimizeLess is equivalent to -O1
	OptimizeLess
	// OptimizeDefault is equivalent to -O2
	OptimizeDefault
	// OptimizeAggressive is equivalent to -O3
	OptimizeAggressive
)

type Target

type Target struct {
	Name        string
	Description string
}

func AllTargets

func AllTargets() []Target

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL