Skip to content

Commit

Permalink
winch(x64): Call indirect (#7100)
Browse files Browse the repository at this point in the history
* winch(x64): Call indirect

This change adds support for the `call_indirect` instruction to Winch.

Libcalls are a pre-requisite for supporting `call_indirect` in order to
lazily initialy funcrefs. This change adds support for libcalls to
Winch by introducing a `BuiltinFunctions` struct similar to Cranelift's
`BuiltinFunctionSignatures` struct.

In general, libcalls are handled like any other function call, with the
only difference that given that not all the information to fulfill the
function call might be known up-front, control is given to the caller
for finalizing the call.

The introduction of function references also involves dealing with
pointer-sized loads and stores, so this change also adds the required
functionality to `FuncEnv` and `MacroAssembler` to be pointer aware,
making it straight forward to derive an `OperandSize` or `WasmType` from
the target's pointer size.

Finally, given the complexity of the call_indirect instrunction, this
change bundles an improvement to the register allocator, allowing it to
track the allocatable vs non-allocatable registers, this is done to
avoid any mistakes when allocating/de-allocating registers that are not
alloctable.

--
prtest:full

* Address review comments

* Fix typos
* Better documentation for `new_unchecked`
* Introduce `max` for `BitSet`
* Make allocatable property `u64`

* winch(calls): Overhaul `FnCall`

This commit simplifies `FnCall`'s interface making its usage more
uniform throughout the compiler. In summary, this change:

* Avoids side effects in the `FnCall::new` constructor, and also makes
  it the only constructor.
* Exposes `FnCall::save_live_registers` and
  `FnCall::calculate_call_stack_space` to calculate the stack space
  consumed by the call and so that the caller can decide which one to
  use at callsites depending on their use-case.

* tests: Fix regset tests
  • Loading branch information
saulecabrera authored Sep 29, 2023
1 parent 11a6608 commit 4b288ba
Show file tree
Hide file tree
Showing 30 changed files with 1,626 additions and 275 deletions.
8 changes: 7 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,17 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
// We ignore tests that assert for traps on windows, given
// that Winch doesn't encode unwind information for Windows, yet.
if strategy == "Winch" {
if testsuite == "misc_testsuite" {
// The misc/call_indirect is fully supported by Winch.
if testname == "call_indirect" {
return false;
}
}
if testsuite != "winch" {
return true;
}

let assert_trap = ["i32", "i64"].contains(&testname);
let assert_trap = ["i32", "i64", "call_indirect"].contains(&testname);

if assert_trap && env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() == "windows" {
return true;
Expand Down
2 changes: 1 addition & 1 deletion crates/winch/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl wasmtime_environ::Compiler for Compiler {
let mut validator = validator.into_validator(self.take_allocations());
let buffer = self
.isa
.compile_function(ty, &body, &translation, &mut validator)
.compile_function(ty, types, &body, &translation, &mut validator)
.map_err(|e| CompileError::Codegen(format!("{e:?}")));
self.save_allocations(validator.into_allocations());
let buffer = buffer?;
Expand Down
3 changes: 2 additions & 1 deletion fuzz/fuzz_targets/differential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,8 @@ fn winch_supports_module(module: &[u8]) -> bool {
| F32Abs { .. }
| F64Abs { .. }
| F32Neg { .. }
| F64Neg { .. } => {}
| F64Neg { .. }
| CallIndirect { .. } => {}
_ => {
supported = false;
break 'main;
Expand Down
Loading

0 comments on commit 4b288ba

Please sign in to comment.