Documentation
¶
Overview ¶
Package backend must be free of Wasm-specific concept. In other words, this package must not import internal/wasm package.
Index ¶
Constants ¶
const ( // ABIArgKindReg represents an argument passed in a register. ABIArgKindReg = iota // ABIArgKindStack represents an argument passed in the stack. ABIArgKindStack )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ABIArg ¶
type ABIArg struct { // Index is the index of the argument. Index int // Kind is the kind of the argument. Kind ABIArgKind // Reg is valid if Kind == ABIArgKindReg. // This VReg must be based on RealReg. Reg regalloc.VReg // Offset is valid if Kind == ABIArgKindStack. // This is the offset from the beginning of either arg or ret stack slot. Offset int64 // Type is the type of the argument. Type ssa.Type }
ABIArg represents either argument or return value's location.
type Compiler ¶
type Compiler interface { // SSABuilder returns the ssa.Builder used by this compiler. SSABuilder() ssa.Builder // Compile executes the following steps: // 1. Lower() // 2. RegAlloc() // 3. Finalize() // 4. Encode() // // Each step can be called individually for testing purpose, therefore they are exposed in this interface too. // // The returned byte slices are the machine code and the relocation information for the machine code. // The caller is responsible for copying them immediately since the compiler may reuse the buffer. Compile(ctx context.Context) (_ []byte, _ []RelocationInfo, _ error) // Lower lowers the given ssa.Instruction to the machine-specific instructions. Lower() // RegAlloc performs the register allocation after Lower is called. RegAlloc() // Finalize performs the finalization of the compilation. This must be called after RegAlloc. Finalize() // Encode encodes the machine code to the buffer. Encode() // Buf returns the buffer of the encoded machine code. This is only used for testing purpose. Buf() []byte // Format returns the debug string of the current state of the compiler. Format() string // Init initializes the internal state of the compiler for the next compilation. Init() // AllocateVReg allocates a new virtual register of the given type. AllocateVReg(typ ssa.Type) regalloc.VReg // ValueDefinition returns the definition of the given value. ValueDefinition(ssa.Value) *SSAValueDefinition // VRegOf returns the virtual register of the given ssa.Value. VRegOf(value ssa.Value) regalloc.VReg // TypeOf returns the ssa.Type of the given virtual register. TypeOf(regalloc.VReg) ssa.Type // MatchInstr returns true if the given definition is from an instruction with the given opcode, the current group ID, // and a refcount of 1. That means, the instruction can be merged/swapped within the current instruction group. MatchInstr(def *SSAValueDefinition, opcode ssa.Opcode) bool // MatchInstrOneOf is the same as MatchInstr but for multiple opcodes. If it matches one of ssa.Opcode, // this returns the opcode. Otherwise, this returns ssa.OpcodeInvalid. // // Note: caller should be careful to avoid excessive allocation on opcodes slice. MatchInstrOneOf(def *SSAValueDefinition, opcodes []ssa.Opcode) ssa.Opcode // AddRelocationInfo appends the relocation information for the function reference at the current buffer offset. AddRelocationInfo(funcRef ssa.FuncRef) // AddSourceOffsetInfo appends the source offset information for the given offset. AddSourceOffsetInfo(executableOffset int64, sourceOffset ssa.SourceOffset) // SourceOffsetInfo returns the source offset information for the current buffer offset. SourceOffsetInfo() []SourceOffsetInfo // Emit4Bytes appends 4 bytes to the buffer. Used during the code emission. Emit4Bytes(b uint32) }
Compiler is the backend of wazevo which takes ssa.Builder and Machine, use the information there to emit the final machine code.
type FunctionABI ¶
type FunctionABI interface { // CalleeGenFunctionArgsToVRegs generates instructions to move arguments to virtual registers. CalleeGenFunctionArgsToVRegs(regs []ssa.Value) // CalleeGenVRegsToFunctionReturns generates instructions to move virtual registers to a return value locations. CalleeGenVRegsToFunctionReturns(regs []ssa.Value) }
FunctionABI represents an ABI for the specific target combined with the function signature.
type Machine ¶
type Machine interface { // DisableStackCheck disables the stack check for the current compilation for debugging/testing. DisableStackCheck() // RegisterInfo returns the set of registers that can be used for register allocation. // This is only called once, and the result is shared across all compilations. RegisterInfo() *regalloc.RegisterInfo // InitializeABI initializes the FunctionABI for the given signature. InitializeABI(sig *ssa.Signature) // ABI returns the FunctionABI used for the currently compiled function. ABI() FunctionABI // SetCompiler sets the compilation context used for the lifetime of Machine. // This is only called once per Machine, i.e. before the first compilation. SetCompiler(Compiler) // StartLoweringFunction is called when the lowering of the given function is started. // maximumBlockID is the maximum value of ssa.BasicBlockID existing in the function. StartLoweringFunction(maximumBlockID ssa.BasicBlockID) // StartBlock is called when the compilation of the given block is started. // The order of this being called is the reverse post order of the ssa.BasicBlock(s) as we iterate with // ssa.Builder BlockIteratorReversePostOrderBegin and BlockIteratorReversePostOrderEnd. StartBlock(ssa.BasicBlock) // LowerSingleBranch is called when the compilation of the given single branch is started. LowerSingleBranch(b *ssa.Instruction) // LowerConditionalBranch is called when the compilation of the given conditional branch is started. LowerConditionalBranch(b *ssa.Instruction) // LowerInstr is called for each instruction in the given block except for the ones marked as already lowered // via Compiler.MarkLowered. The order is reverse, i.e. from the last instruction to the first one. // // Note: this can lower multiple instructions (which produce the inputs) at once whenever it's possible // for optimization. LowerInstr(*ssa.Instruction) // EndBlock is called when the compilation of the current block is finished. EndBlock() // LinkAdjacentBlocks is called after finished lowering all blocks in order to create one single instruction list. LinkAdjacentBlocks(prev, next ssa.BasicBlock) // EndLoweringFunction is called when the lowering of the current function is finished. EndLoweringFunction() // Reset resets the machine state for the next compilation. Reset() // FlushPendingInstructions flushes the pending instructions to the buffer. // This will be called after the lowering of each SSA Instruction. FlushPendingInstructions() // InsertMove inserts a move instruction from src to dst whose type is typ. InsertMove(dst, src regalloc.VReg, typ ssa.Type) // InsertReturn inserts the return instruction to return from the current function. InsertReturn() // InsertLoadConstant inserts the instruction(s) to load the constant value into the given regalloc.VReg. InsertLoadConstant(instr *ssa.Instruction, vr regalloc.VReg) // Format returns the string representation of the currently compiled machine code. // This is only for testing purpose. Format() string // Function returns the currently compiled state as regalloc.Function so that we can perform register allocation. Function() regalloc.Function // SetupPrologue inserts the prologue after register allocations. SetupPrologue() // SetupEpilogue inserts the epilogue after register allocations. // This sets up the instructions for the inverse of SetupPrologue right before SetupEpilogue() // ResolveRelativeAddresses resolves the relative addresses after register allocations and prologue/epilogue setup. // After this, the compiler is finally ready to emit machine code. ResolveRelativeAddresses() // ResolveRelocations resolves the relocations after emitting machine code. ResolveRelocations(refToBinaryOffset map[ssa.FuncRef]int, binary []byte, relocations []RelocationInfo) // Encode encodes the machine instructions to the Compiler. Encode() // CompileGoFunctionTrampoline compiles the trampoline function to call a Go function of the given exit code and signature. CompileGoFunctionTrampoline(exitCode wazevoapi.ExitCode, sig *ssa.Signature, needModuleContextPtr bool) []byte // CompileStackGrowCallSequence returns the sequence of instructions shared by all functions to // call the stack grow builtin function. CompileStackGrowCallSequence() []byte // CompileEntryPreamble returns the sequence of instructions shared by multiple functions to // enter the function from Go. CompileEntryPreamble(signature *ssa.Signature) []byte }
Machine is a backend for a specific ISA machine.
type RelocationInfo ¶
type RelocationInfo struct { // Offset represents the offset from the beginning of the machine code of either a function or the entire module. Offset int64 // Target is the target function of the call instruction. FuncRef ssa.FuncRef }
RelocationInfo represents the relocation information for a call instruction.
type SSAValueDefinition ¶
type SSAValueDefinition struct { // BlockParamValue is valid if Instr == nil BlockParamValue ssa.Value // BlkParamVReg is valid if Instr == nil BlkParamVReg regalloc.VReg // Instr is not nil if this is a definition from an instruction. Instr *ssa.Instruction // N is the index of the return value in the instr's return values list. N int // RefCount is the number of references to the result. RefCount int }
SSAValueDefinition represents a definition of an SSA value.
func (*SSAValueDefinition) IsFromBlockParam ¶
func (d *SSAValueDefinition) IsFromBlockParam() bool
func (*SSAValueDefinition) IsFromInstr ¶
func (d *SSAValueDefinition) IsFromInstr() bool
func (*SSAValueDefinition) SSAValue ¶
func (d *SSAValueDefinition) SSAValue() ssa.Value
type SourceOffsetInfo ¶
type SourceOffsetInfo struct { // SourceOffset is the source offset in the original source code. SourceOffset ssa.SourceOffset // ExecutableOffset is the offset in the compiled executable. ExecutableOffset int64 }
SourceOffsetInfo is a data to associate the source offset with the executable offset.