Skip to content

Commit 3250c98

Browse files
authored
Add Strategy::Winch and RegallocAlgorithm support to the C and C++ API (#13155)
* Add `Strategy::Winch` support to the C/C++ API * Add support for setting the Cranelift regalloc algorithm via the C/C++ API
1 parent 0b2a3af commit 3250c98

File tree

4 files changed

+107
-1
lines changed

4 files changed

+107
-1
lines changed

crates/c-api/include/wasmtime/config.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ enum wasmtime_strategy_enum { // Strategy
3434
/// Indicates that Wasmtime will unconditionally use Cranelift to compile
3535
/// WebAssembly code.
3636
WASMTIME_STRATEGY_CRANELIFT,
37+
38+
/// Indicates that Wasmtime will unconditionally use Winch to compile
39+
/// WebAssembly code.
40+
//
41+
/// For more details regarding ISA support and Wasm proposals support
42+
/// see <https://docs.wasmtime.dev/stability-tiers.html#current-tier-status>
43+
WASMTIME_STRATEGY_WINCH,
3744
};
3845

3946
/**
@@ -87,6 +94,39 @@ enum wasmtime_profiling_strategy_enum { // ProfilingStrategy
8794
WASMTIME_PROFILING_STRATEGY_PERFMAP,
8895
};
8996

97+
/**
98+
* \brief Different ways Cranelift can allocate registers
99+
*
100+
* See #wasmtime_regalloc_algorithm_enum for possible values.
101+
*/
102+
typedef uint8_t wasmtime_regalloc_algorithm_t;
103+
104+
/**
105+
* \brief Different ways to allocate registers.
106+
*
107+
* The default is #WASMTIME_REGALLOC_BACKTRACKING.
108+
*/
109+
enum wasmtime_regalloc_algorithm_enum { // RegallocAlgorithm
110+
/// Generates the fastest possible code, but may take longer.
111+
///
112+
/// This algorithm performs “backtracking”, which means that it may undo
113+
/// its earlier work and retry as it discovers conflicts. This results
114+
/// in better register utilization, producing fewer spills and moves,
115+
/// but can cause super-linear compile runtime.
116+
WASMTIME_REGALLOC_BACKTRACKING,
117+
/// Generates acceptable code very quickly.
118+
///
119+
/// This algorithm performs a single pass through the code, guaranteed to work
120+
/// in linear time.
121+
/// (Note that the rest of Cranelift is not necessarily guaranteed to run in
122+
/// linear time, however.)
123+
/// It cannot undo earlier decisions, however, and it cannot foresee
124+
/// constraints or issues that may
125+
/// occur further ahead in the code, so the code may have more spills and
126+
/// moves as a result.
127+
WASMTIME_REGALLOC_SINGLE_PASS,
128+
};
129+
90130
#define WASMTIME_CONFIG_PROP(ret, name, ty) \
91131
WASM_API_EXTERN ret wasmtime_config_##name##_set(wasm_config_t *, ty);
92132

@@ -342,6 +382,15 @@ WASMTIME_CONFIG_PROP(void, cranelift_nan_canonicalization, bool)
342382
*/
343383
WASMTIME_CONFIG_PROP(void, cranelift_opt_level, wasmtime_opt_level_t)
344384

385+
/**
386+
* \brief Configures the regalloc algorithm used by the Cranelift code
387+
* generator.
388+
*
389+
* This setting in #WASMTIME_REGALLOC_BACKTRACKING by default.
390+
*/
391+
WASMTIME_CONFIG_PROP(void, cranelift_regalloc_algorithm,
392+
wasmtime_regalloc_algorithm_t)
393+
345394
#endif // WASMTIME_FEATURE_COMPILER
346395

347396
/**

crates/c-api/include/wasmtime/config.hh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ enum class Strategy {
1919
Auto = WASMTIME_STRATEGY_AUTO,
2020
/// Requires Cranelift to be used for compilation
2121
Cranelift = WASMTIME_STRATEGY_CRANELIFT,
22+
/// Use winch for compilation
23+
Winch = WASMTIME_STRATEGY_WINCH,
2224
};
2325

2426
/// \brief Values passed to `Config::cranelift_opt_level`
@@ -43,6 +45,30 @@ enum class ProfilingStrategy {
4345
Perfmap = WASMTIME_PROFILING_STRATEGY_PERFMAP,
4446
};
4547

48+
/// \brief Values passed to `Config::cranelift_regalloc_algorithm`
49+
enum RegallocAlgorithm {
50+
/// Generates the fastest possible code, but may take longer.
51+
///
52+
/// This algorithm performs “backtracking”, which means that it may undo its
53+
/// earlier work
54+
/// and retry as it discovers conflicts. This results in better register
55+
/// utilization,
56+
/// producing fewer spills and moves, but can cause super-linear compile
57+
/// runtime.
58+
Backtracking = WASMTIME_REGALLOC_BACKTRACKING,
59+
/// Generates acceptable code very quickly.
60+
///
61+
/// This algorithm performs a single pass through the code, guaranteed to work
62+
/// in linear time.
63+
/// (Note that the rest of Cranelift is not necessarily guaranteed to run in
64+
/// linear time, however.)
65+
/// It cannot undo earlier decisions, however, and it cannot foresee
66+
/// constraints or issues that may
67+
/// occur further ahead in the code, so the code may have more spills and
68+
/// moves as a result.
69+
SinglePass = WASMTIME_REGALLOC_SINGLE_PASS,
70+
};
71+
4672
#ifdef WASMTIME_FEATURE_POOLING_ALLOCATOR
4773
/**
4874
* \brief Pool allocation configuration for Wasmtime.
@@ -477,6 +503,14 @@ class Config {
477503
void cranelift_flag_set(const std::string &flag, const std::string &value) {
478504
wasmtime_config_cranelift_flag_set(ptr.get(), flag.c_str(), value.c_str());
479505
}
506+
507+
/// \brief Configures cranelift's register allocation mode
508+
///
509+
/// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.cranelift_regalloc_algorithm
510+
void cranelift_regalloc_algorithm(RegallocAlgorithm algo) {
511+
wasmtime_config_cranelift_regalloc_algorithm_set(
512+
ptr.get(), static_cast<wasmtime_regalloc_algorithm_t>(algo));
513+
}
480514
#endif // WASMTIME_FEATURE_COMPILER
481515

482516
/// \brief Configures an active wasm profiler

crates/c-api/src/config.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::ptr;
88
use std::{ffi::CStr, sync::Arc};
99
use wasmtime::{
1010
Config, InstanceAllocationStrategy, LinearMemory, MemoryCreator, OptLevel, ProfilingStrategy,
11-
Result, Strategy,
11+
RegallocAlgorithm, Result, Strategy,
1212
};
1313

1414
#[cfg(feature = "pooling-allocator")]
@@ -27,6 +27,7 @@ wasmtime_c_api_macros::declare_own!(wasm_config_t);
2727
pub enum wasmtime_strategy_t {
2828
WASMTIME_STRATEGY_AUTO,
2929
WASMTIME_STRATEGY_CRANELIFT,
30+
WASMTIME_STRATEGY_WINCH,
3031
}
3132

3233
#[repr(u8)]
@@ -46,6 +47,13 @@ pub enum wasmtime_profiling_strategy_t {
4647
WASMTIME_PROFILING_STRATEGY_PERFMAP,
4748
}
4849

50+
#[repr(u8)]
51+
#[derive(Clone)]
52+
pub enum wasmtime_regalloc_algorithm_t {
53+
WASMTIME_REGALLOC_BACKTRACKING,
54+
WASMTIME_REGALLOC_SINGLE_PASS,
55+
}
56+
4957
#[unsafe(no_mangle)]
5058
pub extern "C" fn wasm_config_new() -> Box<wasm_config_t> {
5159
Box::new(wasm_config_t {
@@ -168,6 +176,7 @@ pub extern "C" fn wasmtime_config_strategy_set(
168176
c.config.strategy(match strategy {
169177
WASMTIME_STRATEGY_AUTO => Strategy::Auto,
170178
WASMTIME_STRATEGY_CRANELIFT => Strategy::Cranelift,
179+
WASMTIME_STRATEGY_WINCH => Strategy::Winch,
171180
});
172181
}
173182

@@ -209,6 +218,19 @@ pub extern "C" fn wasmtime_config_cranelift_opt_level_set(
209218
});
210219
}
211220

221+
#[unsafe(no_mangle)]
222+
#[cfg(any(feature = "cranelift", feature = "winch"))]
223+
pub extern "C" fn wasmtime_config_cranelift_regalloc_algorithm_set(
224+
c: &mut wasm_config_t,
225+
algo: wasmtime_regalloc_algorithm_t,
226+
) {
227+
use wasmtime_regalloc_algorithm_t::*;
228+
c.config.cranelift_regalloc_algorithm(match algo {
229+
WASMTIME_REGALLOC_BACKTRACKING => RegallocAlgorithm::Backtracking,
230+
WASMTIME_REGALLOC_SINGLE_PASS => RegallocAlgorithm::SinglePass,
231+
});
232+
}
233+
212234
#[unsafe(no_mangle)]
213235
pub extern "C" fn wasmtime_config_profiler_set(
214236
c: &mut wasm_config_t,

crates/c-api/tests/config.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ TEST(Config, Smoke) {
5656
config.strategy(Strategy::Auto);
5757
config.cranelift_debug_verifier(false);
5858
config.cranelift_opt_level(OptLevel::Speed);
59+
config.cranelift_regalloc_algorithm(RegallocAlgorithm::Backtracking);
5960
config.cranelift_nan_canonicalization(false);
6061
config.profiler(ProfilingStrategy::None);
6162
config.memory_reservation(0);

0 commit comments

Comments
 (0)