github.com/AR1011/wazero@v1.0.5/internal/engine/wazevo/backend/machine.go (about)

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