Add a cranelift compile-time feature to wasmtime (#3206)
* Remove unnecessary into_iter/map Forgotten from a previous refactoring, this variable was already of the right type! * Move `wasmtime_jit::Compiler` into `wasmtime` This `Compiler` struct is mostly a historical artifact at this point and wasn't necessarily pulling much weight any more. This organization also doesn't lend itself super well to compiling out `cranelift` when the `Compiler` here is used for both parallel iteration configuration settings as well as compilation. The movement into `wasmtime` is relatively small, with `Module::build_artifacts` being the main function added here which is a merging of the previous functions removed from the `wasmtime-jit` crate. * Add a `cranelift` compile-time feature to `wasmtime` This commit concludes the saga of refactoring Wasmtime and making Cranelift an optional dependency by adding a new Cargo feature to the `wasmtime` crate called `cranelift`, which is enabled by default. This feature is implemented by having a new cfg for `wasmtime` itself, `cfg(compiler)`, which is used wherever compilation is necessary. This bubbles up to disable APIs such as `Module::new`, `Func::new`, `Engine::precompile_module`, and a number of `Config` methods affecting compiler configuration. Checks are added to CI that when built in this mode Wasmtime continues to successfully build. It's hoped that although this is effectively "sprinkle `#[cfg]` until things compile" this won't be too too bad to maintain over time since it's also an use case we're interested in supporting. With `cranelift` disabled the only way to create a `Module` is with the `Module::deserialize` method, which requires some form of precompiled artifact. Two consequences of this change are: * `Module::serialize` is also disabled in this mode. The reason for this is that serialized modules contain ISA/shared flags encoded in them which were used to produce the compiled code. There's no storage for this if compilation is disabled. This could probably be re-enabled in the future if necessary, but it may not end up being all that necessary. * Deserialized modules are not checked to ensure that their ISA/shared flags are compatible with the host CPU. This is actually already the case, though, with normal modules. We'll likely want to fix this in the future using a shared implementation for both these locations. Documentation should be updated to indicate that `cranelift` can be disabled, although it's not really the most prominent documentation because this is expected to be a somewhat niche use case (albeit important, just not too common). * Always enable cranelift for the C API * Fix doc example builds * Fix check tests on GitHub Actions
This commit is contained in:
@@ -5,7 +5,6 @@ use std::collections::BTreeMap;
|
||||
use std::str::FromStr;
|
||||
use structopt::StructOpt;
|
||||
use wasmtime_environ::{FlagValue, Setting, SettingKind};
|
||||
use wasmtime_jit::Compiler;
|
||||
|
||||
/// Displays available Cranelift settings for a target.
|
||||
#[derive(StructOpt)]
|
||||
@@ -19,7 +18,7 @@ pub struct SettingsCommand {
|
||||
impl SettingsCommand {
|
||||
/// Executes the command.
|
||||
pub fn execute(self) -> Result<()> {
|
||||
let mut builder = Compiler::builder(wasmtime_jit::CompilationStrategy::Auto);
|
||||
let mut builder = wasmtime_cranelift::builder();
|
||||
if let Some(target) = &self.target {
|
||||
let target = target_lexicon::Triple::from_str(target).map_err(|e| anyhow!(e))?;
|
||||
builder.target(target)?;
|
||||
|
||||
34
src/obj.rs
34
src/obj.rs
@@ -1,9 +1,9 @@
|
||||
use anyhow::{bail, Context as _, Result};
|
||||
use std::mem;
|
||||
use target_lexicon::Triple;
|
||||
use wasmparser::WasmFeatures;
|
||||
use wasmtime::Strategy;
|
||||
use wasmtime_environ::{ModuleEnvironment, Tunables};
|
||||
use wasmtime_jit::Compiler;
|
||||
use wasmtime_environ::{ModuleEnvironment, PrimaryMap, Tunables};
|
||||
|
||||
/// Creates object file from binary wasm data.
|
||||
pub fn compile_to_obj(
|
||||
@@ -14,16 +14,11 @@ pub fn compile_to_obj(
|
||||
opt_level: wasmtime::OptLevel,
|
||||
debug_info: bool,
|
||||
) -> Result<Vec<u8>> {
|
||||
let strategy = match strategy {
|
||||
Strategy::Auto => wasmtime_jit::CompilationStrategy::Auto,
|
||||
Strategy::Cranelift => wasmtime_jit::CompilationStrategy::Cranelift,
|
||||
#[cfg(feature = "lightbeam")]
|
||||
Strategy::Lightbeam => wasmtime_jit::CompilationStrategy::Lightbeam,
|
||||
#[cfg(not(feature = "lightbeam"))]
|
||||
Strategy::Lightbeam => bail!("lightbeam support not enabled"),
|
||||
s => bail!("unknown compilation strategy {:?}", s),
|
||||
};
|
||||
let mut builder = Compiler::builder(strategy);
|
||||
match strategy {
|
||||
Strategy::Cranelift | Strategy::Auto => {}
|
||||
other => panic!("unsupported strategy {:?}", other),
|
||||
}
|
||||
let mut builder = wasmtime_cranelift::builder();
|
||||
if let Some(target) = target {
|
||||
builder.target(target.clone())?;
|
||||
}
|
||||
@@ -50,12 +45,21 @@ pub fn compile_to_obj(
|
||||
tunables.generate_native_debuginfo = debug_info;
|
||||
tunables.parse_wasm_debuginfo = debug_info;
|
||||
|
||||
let compiler = Compiler::new(&*builder, tunables.clone(), features.clone(), true);
|
||||
let compiler = builder.build();
|
||||
let environ = ModuleEnvironment::new(&tunables, &features);
|
||||
let (_main_module, mut translation, types) = environ
|
||||
.translate(wasm)
|
||||
.context("failed to translate module")?;
|
||||
assert_eq!(translation.len(), 1);
|
||||
let compilation = compiler.compile(&mut translation[0], &types)?;
|
||||
Ok(compilation.obj)
|
||||
let mut funcs = PrimaryMap::default();
|
||||
for (index, func) in mem::take(&mut translation[0].function_body_inputs) {
|
||||
funcs.push(compiler.compile_function(&translation[0], index, func, &tunables, &types)?);
|
||||
}
|
||||
let (obj, _) = compiler.emit_obj(
|
||||
&translation[0],
|
||||
&types,
|
||||
funcs,
|
||||
tunables.generate_native_debuginfo,
|
||||
)?;
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user