You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

27 lines
611 B

Initial skeleton for Winch (#4907) * Initial skeleton for Winch This commit introduces the initial skeleton for Winch, the "baseline" compiler. This skeleton contains mostly setup code for the ISA, ABI, registers, and compilation environment abstractions. It also includes the calculation of function local slots. As of this commit, the structure of these abstractions looks like the following: +------------------------+ | v +----------+ +-----+ +-----------+-----+-----------------+ | Compiler | --> | ISA | --> | Registers | ABI | Compilation Env | +----------+ +-----+ +-----------+-----+-----------------+ | ^ +------------------------------+ * Compilation environment will hold a reference to the function data * Add basic documentation to the ABI trait * Enable x86 and arm64 in cranelift-codegen * Add reg_name function for x64 * Introduce the concept of a MacroAssembler and Assembler This commit introduces the concept of a MacroAsesembler and Assembler. The MacroAssembler trait will provide a high enough interface across architectures so that each ISA implementation can use their own low-level Assembler implementation to fulfill the interface. Each Assembler will provide a 1-1 mapping to each ISA instruction. As of this commit, only a partial debug implementation is provided for the x64 Assembler. * Add a newtype over PReg Adds a newtype `Reg` over regalloc2::PReg; this ensures that Winch will operate only on the concept of `Reg`. This change is temporary until we have the necessary machinery to share a common Reg abstraction via `cranelift_asm` * Improvements to local calcuation - Add `LocalSlot::addressed_from_sp` - Use `u32` for local slot and local sizes calculation * Add helper methods to ABIArg Adds helper methods to retrieve register and type information from the argument * Make locals_size public in frame * Improve x64 register naming depending on size * Add new methods to the masm interface This commit introduces the ability for the MacroAssembler to reserve stack space, get the address of a given local and perform a stack store based on the concept of `Operand`s. There are several motivating factors to introduce the concept of an Operand: - Make the translation between Winch and Cranelift easier; - Make dispatching from the MacroAssembler to the underlying Assembler - easier by minimizing the amount of functions that we need to define - in order to satisfy the store/load combinations This commit also introduces the concept of a memory address, which essentially describes the addressing modes; as of this commit only one addressing mode is supported. We'll also need to verify that this structure will play nicely with arm64. * Blank masm implementation for arm64 * Implementation of reserve_stack, local_address, store and fp_offset for x64 * Implement function prologue and argument register spilling * Add structopt and wat * Fix debug instruction formatting * Make TargetISA trait publicly accessible * Modify the MacroAssembler finalize siganture to return a slice of strings * Introduce a simple CLI for Winch To be able to compile Wasm programs with Winch independently. Mostly meant for testing / debugging * Fix bug in x64 assembler mov_rm * Remove unused import * Move the stack slot calculation to the Frame This commit moves the calculation of the stack slots to the frame handler abstraction and also includes the calculation of the limits for the function defined locals, which will be used to zero the locals that are not associated to function arguments * Add i32 and i64 constructors to local slots * Introduce the concept of DefinedLocalsRange This commit introduces `DefinedLocalsRange` to track the stack offset at which the function-defined locals start and end; this is later used to zero-out that stack region * Add constructors for int and float registers * Add a placeholder stack implementation * Add a regset abstraction to track register availability Adds a bit set abstraction to track register availability for register allocation. The bit set has no specific knowledge about physical registers, it works on the register's hardware encoding as the source of truth. Each RegSet is expected to be created with the universe of allocatable registers per ISA when starting the compilation of a particular function. * Add an abstraction over register and immediate This is meant to be used as the source for stores. * Add a way to zero local slots and an initial skeletion of regalloc This commit introduces `zero_local_slots` to the MacroAssembler; which ensures that function defined locals are zeroed out when starting the function body. The algorithm divides the defined function locals stack range into 8 byte slots and stores a zero at each address. This process relies on register allocation if the amount of slots that need to be initialized is greater than 1. In such case, the next available register is requested to the register set and it's used to store a 0, which is then stored at every local slot * Update to wasmparser 0.92 * Correctly track if the regset has registers available * Add a result entry to the ABI signature This commuit introduces ABIResult as part of the ABISignature; this struct will track how function results are stored; initially it will consiste of a single register that will be requested to the register allocator at the end of the function; potentially causing a spill * Move zero local slots and add more granular methods to the masm This commit removes zeroing local slots from the MacroAssembler and instead adds more granular methods to it (e.g `zero`, `add`). This allows for better code sharing since most of the work done by the algorithm for zeroing slots will be the same in all targets, except for the binary emissions pieces, which is what gets delegated to the masm * Use wasmparser's visitor API and add initial support for const and add This commit adds initial support for the I32Const and I32 instructions; this involves adding a minimum for register allocation. Note that some regalloc pieces are still incomplete, since for the current set of supported instructions they are not needed. * Make the ty field public in Local * Add scratch_reg to the abi * Add a method to get a particular local from the Frame * Split the compilation environment abstraction This commit splits the compilation environment into two more concise abstractions: 1. CodeGen: the main abstraction for code generation 2. CodeGenContext: abstraction that shares the common pieces for compilation; these pieces are shared between the code generator and the register allocator * Add `push` and `load` to the MacroAssembler * Remove dead code warnings for unused paths * Map ISA features to cranelift-codegen ISA features * Apply formatting * Fix Cargo.toml after a bad rebase * Add component-compiler feature * Use clap instead of structopt * Add winch to publish.rs script * Minor formatting * Add tests to RegSet and fix two bugs when freeing and checking for register availability * Add tests to Stack * Free source register after a non-constant i32 add * Improve comments - Remove unneeded comments - And improve some of the TODO items * Update default features * Drop the ABI generic param and pass the word_size information directly To avoid dealing with dead code warnings this commit passes the word size information directly, since it's the only piece of information needed from the ABI by Codegen until now * Remove dead code This piece of code will be put back once we start integrating Winch with Wasmtime * Remove unused enum variant This variant doesn't get constructed; it should be added back once a backend is added and not enabled by default or when Winch gets integrated into Wasmtime * Fix unused code in regset tests * Update spec testsuite * Switch the visitor pattern for a simpler operator match This commit removes the usage of wasmparser's visitor pattern and instead defaults to a simpler operator matching approach. This removes the complexity of having to define all the visitor trait functions at once. * Use wasmparser's Visitor trait with a different macro strategy This commit puts back wasmparser's Visitor trait, with a sigle; simpler macro, only used for unsupported operators. * Restructure Winch This commit restuructures Winch's parts. It divides the initial approach into three main crates: `winch-codegen`,`wasmtime-winch` and `winch-tools`. `wasmtime-winch` is reponsible for the Wasmtime-Winch integration. `winch-codegen` is solely responsible for code generation. `winch-tools` is CLI tool to compile Wasm programs, mainly for testing purposes. * Refactor zero local slots This commit moves the logic of zeroing local slots from the codegen module into a method with a default implementation in the MacroAssembler trait: `zero_mem_range`. The refactored implementation is very similar to the previous implementation with the only difference that it doesn't allocates a general-purpose register; it instead uses the register allocator to retrieve the scratch register and uses this register to unroll the series of zero stores. * Tie the codegen creation to the ISA ABI This commit makes the relationship between the ISA ABI and the codegen explicit. This allows us to pass down ABI-specific bit and pieces to the codegeneration. In this case the only concrete piece that we need is the ABI word size. * Mark winch as publishable directory * Revamp winch docs This commit ensures that all the code comments in Winch are compliant with the syle used in the rest of Wasmtime's codebase. It also imptoves, generally the quality of the comments in some modules. * Panic when using multi-value when the target is aarch64 Similar to x64, this commit ensures that the abi signature of the current function doesn't use multi-value returns * Document the usage of directives * Use endianness instead of endianess in the ISA trait * Introduce a three-argument form in the MacroAssembler This commit introduces the usage of three-argument form for the MacroAssembler interface. This allows for a natural mapping for architectures like aarch64. In the case of x64, the implementation can simply restrict the implementation asserting for equality in two of the arguments of defaulting to a differnt set of instructions. As of this commit, the implementation of `add` panics if the destination and the first source arguments are not equal; internally the x64 assembler implementation will ensure that all the allowed combinations of `add` are satisfied. The reason for panicking and not emitting a `mov` followed by an `add` for example is simply because register allocation happens right before calling `add`, which ensures any register-to-register moves, if needed. This implementation will evolve in the future and this panic will be lifted if needed. * Improve the documentation for the MacroAssembler. Documents the usage of three-arg form and the intention around the high-level interface. * Format comments in remaining modules * Clean up Cargo.toml for winch pieces This commit adds missing fields to each of Winch's Cargo.toml. * Use `ModuleTranslation::get_types()` to derive the function type * Assert that start range is always word-size aligned
2 years ago
[package]
name = "winch-tools"
version = "0.1.0"
description = "Binaries for testing Winch"
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/bytecodealliance/wasmtime"
publish = false
edition.workspace = true
[[bin]]
name = "winch-tools"
path = "src/main.rs"
[dependencies]
winch-codegen = { workspace = true }
wasmtime-environ = { workspace = true }
Implement AOT compilation for components (#5160) * Pull `Module` out of `ModuleTextBuilder` This commit is the first in what will likely be a number towards preparing for serializing a compiled component to bytes, a precompiled artifact. To that end my rough plan is to merge all of the compiled artifacts for a component into one large object file instead of having lots of separate object files and lots of separate mmaps to manage. To that end I plan on eventually using `ModuleTextBuilder` to build one large text section for all core wasm modules and trampolines, meaning that `ModuleTextBuilder` is no longer specific to one module. I've extracted out functionality such as function name calculation as well as relocation resolving (now a closure passed in) in preparation for this. For now this just keeps tests passing, and the trajectory for this should become more clear over the following commits. * Remove component-specific object emission This commit removes the `ComponentCompiler::emit_obj` function in favor of `Compiler::emit_obj`, now renamed `append_code`. This involved significantly refactoring code emission to take a flat list of functions into `append_code` and the caller is responsible for weaving together various "families" of functions and un-weaving them afterwards. * Consolidate ELF parsing in `CodeMemory` This commit moves the ELF file parsing and section iteration from `CompiledModule` into `CodeMemory` so one location keeps track of section ranges and such. This is in preparation for sharing much of this code with components which needs all the same sections to get tracked but won't be using `CompiledModule`. A small side benefit from this is that the section parsing done in `CodeMemory` and `CompiledModule` is no longer duplicated. * Remove separately tracked traps in components Previously components would generate an "always trapping" function and the metadata around which pc was allowed to trap was handled manually for components. With recent refactorings the Wasmtime-standard trap section in object files is now being generated for components as well which means that can be reused instead of custom-tracking this metadata. This commit removes the manual tracking for the `always_trap` functions and plumbs the necessary bits around to make components look more like modules. * Remove a now-unnecessary `Arc` in `Module` Not expected to have any measurable impact on performance, but complexity-wise this should make it a bit easier to understand the internals since there's no longer any need to store this somewhere else than its owner's location. * Merge compilation artifacts of components This commit is a large refactoring of the component compilation process to produce a single artifact instead of multiple binary artifacts. The core wasm compilation process is refactored as well to share as much code as necessary with the component compilation process. This method of representing a compiled component necessitated a few medium-sized changes internally within Wasmtime: * A new data structure was created, `CodeObject`, which represents metadata about a single compiled artifact. This is then stored as an `Arc` within a component and a module. For `Module` this is always uniquely owned and represents a shuffling around of data from one owner to another. For a `Component`, however, this is shared amongst all loaded modules and the top-level component. * The "module registry" which is used for symbolicating backtraces and for trap information has been updated to account for a single region of loaded code holding possibly multiple modules. This involved adding a second-level `BTreeMap` for now. This will likely slow down instantiation slightly but if it poses an issue in the future this should be able to be represented with a more clever data structure. This commit additionally solves a number of longstanding issues with components such as compiling only one host-to-wasm trampoline per signature instead of possibly once-per-module. Additionally the `SignatureCollection` registration now happens once-per-component instead of once-per-module-within-a-component. * Fix compile errors from prior commits * Support AOT-compiling components This commit adds support for AOT-compiled components in the same manner as `Module`, specifically adding: * `Engine::precompile_component` * `Component::serialize` * `Component::deserialize` * `Component::deserialize_file` Internally the support for components looks quite similar to `Module`. All the prior commits to this made adding the support here (unsurprisingly) easy. Components are represented as a single object file as are modules, and the functions for each module are all piled into the same object file next to each other (as are areas such as data sections). Support was also added here to quickly differentiate compiled components vs compiled modules via the `e_flags` field in the ELF header. * Prevent serializing exported modules on components The current representation of a module within a component means that the implementation of `Module::serialize` will not work if the module is exported from a component. The reason for this is that `serialize` doesn't actually do anything and simply returns the underlying mmap as a list of bytes. The mmap, however, has `.wasmtime.info` describing component metadata as opposed to this module's metadata. While rewriting this section could be implemented it's not so easy to do so and is otherwise seen as not super important of a feature right now anyway. * Fix windows build * Fix an unused function warning * Update crates/environ/src/compilation.rs Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com> Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
2 years ago
target-lexicon = { workspace = true }
Initial skeleton for Winch (#4907) * Initial skeleton for Winch This commit introduces the initial skeleton for Winch, the "baseline" compiler. This skeleton contains mostly setup code for the ISA, ABI, registers, and compilation environment abstractions. It also includes the calculation of function local slots. As of this commit, the structure of these abstractions looks like the following: +------------------------+ | v +----------+ +-----+ +-----------+-----+-----------------+ | Compiler | --> | ISA | --> | Registers | ABI | Compilation Env | +----------+ +-----+ +-----------+-----+-----------------+ | ^ +------------------------------+ * Compilation environment will hold a reference to the function data * Add basic documentation to the ABI trait * Enable x86 and arm64 in cranelift-codegen * Add reg_name function for x64 * Introduce the concept of a MacroAssembler and Assembler This commit introduces the concept of a MacroAsesembler and Assembler. The MacroAssembler trait will provide a high enough interface across architectures so that each ISA implementation can use their own low-level Assembler implementation to fulfill the interface. Each Assembler will provide a 1-1 mapping to each ISA instruction. As of this commit, only a partial debug implementation is provided for the x64 Assembler. * Add a newtype over PReg Adds a newtype `Reg` over regalloc2::PReg; this ensures that Winch will operate only on the concept of `Reg`. This change is temporary until we have the necessary machinery to share a common Reg abstraction via `cranelift_asm` * Improvements to local calcuation - Add `LocalSlot::addressed_from_sp` - Use `u32` for local slot and local sizes calculation * Add helper methods to ABIArg Adds helper methods to retrieve register and type information from the argument * Make locals_size public in frame * Improve x64 register naming depending on size * Add new methods to the masm interface This commit introduces the ability for the MacroAssembler to reserve stack space, get the address of a given local and perform a stack store based on the concept of `Operand`s. There are several motivating factors to introduce the concept of an Operand: - Make the translation between Winch and Cranelift easier; - Make dispatching from the MacroAssembler to the underlying Assembler - easier by minimizing the amount of functions that we need to define - in order to satisfy the store/load combinations This commit also introduces the concept of a memory address, which essentially describes the addressing modes; as of this commit only one addressing mode is supported. We'll also need to verify that this structure will play nicely with arm64. * Blank masm implementation for arm64 * Implementation of reserve_stack, local_address, store and fp_offset for x64 * Implement function prologue and argument register spilling * Add structopt and wat * Fix debug instruction formatting * Make TargetISA trait publicly accessible * Modify the MacroAssembler finalize siganture to return a slice of strings * Introduce a simple CLI for Winch To be able to compile Wasm programs with Winch independently. Mostly meant for testing / debugging * Fix bug in x64 assembler mov_rm * Remove unused import * Move the stack slot calculation to the Frame This commit moves the calculation of the stack slots to the frame handler abstraction and also includes the calculation of the limits for the function defined locals, which will be used to zero the locals that are not associated to function arguments * Add i32 and i64 constructors to local slots * Introduce the concept of DefinedLocalsRange This commit introduces `DefinedLocalsRange` to track the stack offset at which the function-defined locals start and end; this is later used to zero-out that stack region * Add constructors for int and float registers * Add a placeholder stack implementation * Add a regset abstraction to track register availability Adds a bit set abstraction to track register availability for register allocation. The bit set has no specific knowledge about physical registers, it works on the register's hardware encoding as the source of truth. Each RegSet is expected to be created with the universe of allocatable registers per ISA when starting the compilation of a particular function. * Add an abstraction over register and immediate This is meant to be used as the source for stores. * Add a way to zero local slots and an initial skeletion of regalloc This commit introduces `zero_local_slots` to the MacroAssembler; which ensures that function defined locals are zeroed out when starting the function body. The algorithm divides the defined function locals stack range into 8 byte slots and stores a zero at each address. This process relies on register allocation if the amount of slots that need to be initialized is greater than 1. In such case, the next available register is requested to the register set and it's used to store a 0, which is then stored at every local slot * Update to wasmparser 0.92 * Correctly track if the regset has registers available * Add a result entry to the ABI signature This commuit introduces ABIResult as part of the ABISignature; this struct will track how function results are stored; initially it will consiste of a single register that will be requested to the register allocator at the end of the function; potentially causing a spill * Move zero local slots and add more granular methods to the masm This commit removes zeroing local slots from the MacroAssembler and instead adds more granular methods to it (e.g `zero`, `add`). This allows for better code sharing since most of the work done by the algorithm for zeroing slots will be the same in all targets, except for the binary emissions pieces, which is what gets delegated to the masm * Use wasmparser's visitor API and add initial support for const and add This commit adds initial support for the I32Const and I32 instructions; this involves adding a minimum for register allocation. Note that some regalloc pieces are still incomplete, since for the current set of supported instructions they are not needed. * Make the ty field public in Local * Add scratch_reg to the abi * Add a method to get a particular local from the Frame * Split the compilation environment abstraction This commit splits the compilation environment into two more concise abstractions: 1. CodeGen: the main abstraction for code generation 2. CodeGenContext: abstraction that shares the common pieces for compilation; these pieces are shared between the code generator and the register allocator * Add `push` and `load` to the MacroAssembler * Remove dead code warnings for unused paths * Map ISA features to cranelift-codegen ISA features * Apply formatting * Fix Cargo.toml after a bad rebase * Add component-compiler feature * Use clap instead of structopt * Add winch to publish.rs script * Minor formatting * Add tests to RegSet and fix two bugs when freeing and checking for register availability * Add tests to Stack * Free source register after a non-constant i32 add * Improve comments - Remove unneeded comments - And improve some of the TODO items * Update default features * Drop the ABI generic param and pass the word_size information directly To avoid dealing with dead code warnings this commit passes the word size information directly, since it's the only piece of information needed from the ABI by Codegen until now * Remove dead code This piece of code will be put back once we start integrating Winch with Wasmtime * Remove unused enum variant This variant doesn't get constructed; it should be added back once a backend is added and not enabled by default or when Winch gets integrated into Wasmtime * Fix unused code in regset tests * Update spec testsuite * Switch the visitor pattern for a simpler operator match This commit removes the usage of wasmparser's visitor pattern and instead defaults to a simpler operator matching approach. This removes the complexity of having to define all the visitor trait functions at once. * Use wasmparser's Visitor trait with a different macro strategy This commit puts back wasmparser's Visitor trait, with a sigle; simpler macro, only used for unsupported operators. * Restructure Winch This commit restuructures Winch's parts. It divides the initial approach into three main crates: `winch-codegen`,`wasmtime-winch` and `winch-tools`. `wasmtime-winch` is reponsible for the Wasmtime-Winch integration. `winch-codegen` is solely responsible for code generation. `winch-tools` is CLI tool to compile Wasm programs, mainly for testing purposes. * Refactor zero local slots This commit moves the logic of zeroing local slots from the codegen module into a method with a default implementation in the MacroAssembler trait: `zero_mem_range`. The refactored implementation is very similar to the previous implementation with the only difference that it doesn't allocates a general-purpose register; it instead uses the register allocator to retrieve the scratch register and uses this register to unroll the series of zero stores. * Tie the codegen creation to the ISA ABI This commit makes the relationship between the ISA ABI and the codegen explicit. This allows us to pass down ABI-specific bit and pieces to the codegeneration. In this case the only concrete piece that we need is the ABI word size. * Mark winch as publishable directory * Revamp winch docs This commit ensures that all the code comments in Winch are compliant with the syle used in the rest of Wasmtime's codebase. It also imptoves, generally the quality of the comments in some modules. * Panic when using multi-value when the target is aarch64 Similar to x64, this commit ensures that the abi signature of the current function doesn't use multi-value returns * Document the usage of directives * Use endianness instead of endianess in the ISA trait * Introduce a three-argument form in the MacroAssembler This commit introduces the usage of three-argument form for the MacroAssembler interface. This allows for a natural mapping for architectures like aarch64. In the case of x64, the implementation can simply restrict the implementation asserting for equality in two of the arguments of defaulting to a differnt set of instructions. As of this commit, the implementation of `add` panics if the destination and the first source arguments are not equal; internally the x64 assembler implementation will ensure that all the allowed combinations of `add` are satisfied. The reason for panicking and not emitting a `mov` followed by an `add` for example is simply because register allocation happens right before calling `add`, which ensures any register-to-register moves, if needed. This implementation will evolve in the future and this panic will be lifted if needed. * Improve the documentation for the MacroAssembler. Documents the usage of three-arg form and the intention around the high-level interface. * Format comments in remaining modules * Clean up Cargo.toml for winch pieces This commit adds missing fields to each of Winch's Cargo.toml. * Use `ModuleTranslation::get_types()` to derive the function type * Assert that start range is always word-size aligned
2 years ago
anyhow = { workspace = true }
wasmparser = { workspace = true }
clap = { workspace = true }
wat = { workspace = true }
[features]
default = ["all-arch"]
all-arch = ["winch-codegen/all-arch"]