github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/engine/wazevo/backend/machine.go (about)

     1  package backend
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/bananabytelabs/wazero/internal/engine/wazevo/backend/regalloc"
     7  	"github.com/bananabytelabs/wazero/internal/engine/wazevo/ssa"
     8  	"github.com/bananabytelabs/wazero/internal/engine/wazevo/wazevoapi"
     9  )
    10  
    11  type (
    12  	// Machine is a backend for a specific ISA machine.
    13  	Machine interface {
    14  		ExecutableContext() ExecutableContext
    15  
    16  		// DisableStackCheck disables the stack check for the current compilation for debugging/testing.
    17  		DisableStackCheck()
    18  
    19  		// RegisterInfo returns the set of registers that can be used for register allocation.
    20  		// This is only called once, and the result is shared across all compilations.
    21  		RegisterInfo() *regalloc.RegisterInfo
    22  
    23  		// InitializeABI initializes the FunctionABI for the given signature.
    24  		InitializeABI(sig *ssa.Signature)
    25  
    26  		// ABI returns the FunctionABI used for the currently compiled function.
    27  		ABI() FunctionABI
    28  
    29  		// SetCompiler sets the compilation context used for the lifetime of Machine.
    30  		// This is only called once per Machine, i.e. before the first compilation.
    31  		SetCompiler(Compiler)
    32  
    33  		// StartBlock is called when the compilation of the given block is started.
    34  		// The order of this being called is the reverse post order of the ssa.BasicBlock(s) as we iterate with
    35  		// ssa.Builder BlockIteratorReversePostOrderBegin and BlockIteratorReversePostOrderEnd.
    36  		StartBlock(ssa.BasicBlock)
    37  
    38  		// LowerSingleBranch is called when the compilation of the given single branch is started.
    39  		LowerSingleBranch(b *ssa.Instruction)
    40  
    41  		// LowerConditionalBranch is called when the compilation of the given conditional branch is started.
    42  		LowerConditionalBranch(b *ssa.Instruction)
    43  
    44  		// LowerInstr is called for each instruction in the given block except for the ones marked as already lowered
    45  		// via Compiler.MarkLowered. The order is reverse, i.e. from the last instruction to the first one.
    46  		//
    47  		// Note: this can lower multiple instructions (which produce the inputs) at once whenever it's possible
    48  		// for optimization.
    49  		LowerInstr(*ssa.Instruction)
    50  
    51  		// Reset resets the machine state for the next compilation.
    52  		Reset()
    53  
    54  		// InsertMove inserts a move instruction from src to dst whose type is typ.
    55  		InsertMove(dst, src regalloc.VReg, typ ssa.Type)
    56  
    57  		// InsertReturn inserts the return instruction to return from the current function.
    58  		InsertReturn()
    59  
    60  		// InsertLoadConstant inserts the instruction(s) to load the constant value into the given regalloc.VReg.
    61  		InsertLoadConstant(instr *ssa.Instruction, vr regalloc.VReg)
    62  
    63  		// Format returns the string representation of the currently compiled machine code.
    64  		// This is only for testing purpose.
    65  		Format() string
    66  
    67  		// Function returns the currently compiled state as regalloc.Function so that we can perform register allocation.
    68  		Function() regalloc.Function
    69  
    70  		// SetupPrologue inserts the prologue after register allocations.
    71  		SetupPrologue()
    72  
    73  		// SetupEpilogue inserts the epilogue after register allocations.
    74  		// This sets up the instructions for the inverse of SetupPrologue right before
    75  		SetupEpilogue()
    76  
    77  		// ResolveRelativeAddresses resolves the relative addresses after register allocations and prologue/epilogue setup.
    78  		// After this, the compiler is finally ready to emit machine code.
    79  		ResolveRelativeAddresses(ctx context.Context)
    80  
    81  		// ResolveRelocations resolves the relocations after emitting machine code.
    82  		ResolveRelocations(refToBinaryOffset map[ssa.FuncRef]int, binary []byte, relocations []RelocationInfo)
    83  
    84  		// Encode encodes the machine instructions to the Compiler.
    85  		Encode()
    86  
    87  		// CompileGoFunctionTrampoline compiles the trampoline function  to call a Go function of the given exit code and signature.
    88  		CompileGoFunctionTrampoline(exitCode wazevoapi.ExitCode, sig *ssa.Signature, needModuleContextPtr bool) []byte
    89  
    90  		// CompileStackGrowCallSequence returns the sequence of instructions shared by all functions to
    91  		// call the stack grow builtin function.
    92  		CompileStackGrowCallSequence() []byte
    93  
    94  		// CompileEntryPreamble returns the sequence of instructions shared by multiple functions to
    95  		// enter the function from Go.
    96  		CompileEntryPreamble(signature *ssa.Signature) []byte
    97  	}
    98  )