Skip to content

Commit

Permalink
Add a compile command to Wasmtime.
Browse files Browse the repository at this point in the history
This commit adds a `compile` command to the Wasmtime CLI.

The command can be used to Ahead-Of-Time (AOT) compile WebAssembly modules.

With the `all-arch` feature enabled, AOT compilation can be performed for
non-native architectures (i.e. cross-compilation).

The `Module::compile` method has been added to perform AOT compilation.

A few of the CLI flags relating to "on by default" Wasm features have been
changed to be "--disable-XYZ" flags.

A simple example of using the `wasmtime compile` command:

```text
$ wasmtime compile input.wasm
$ wasmtime input.cwasm
```
  • Loading branch information
peterhuene committed Mar 31, 2021
1 parent 27ce383 commit ccb58e1
Show file tree
Hide file tree
Showing 35 changed files with 1,618 additions and 278 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ vtune = ["wasmtime/vtune"]
wasi-crypto = ["wasmtime-wasi-crypto"]
wasi-nn = ["wasmtime-wasi-nn"]
uffd = ["wasmtime/uffd"]
all-arch = ["wasmtime/all-arch"]

# Try the experimental, work-in-progress new x86_64 backend. This is not stable
# as of June 2020.
Expand Down
31 changes: 30 additions & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@

--------------------------------------------------------------------------------

## Unreleased

### Added

* The `wasmtime compile` command was added to support AOT compilation of Wasm
modules.

* The `Module::compile` method was added to support AOT compilation of a module.

* Added the `Config::cranelift_flag_enable` to enable setting Cranelift boolean
flags or presets in a config.

### Changed

* Breaking: the CLI option `--cranelift-flags` was changed to `--cranelift-flag`.

* Breaking: the CLI option `--enable-reference-types=false` has been changed to
`--disable-reference-types` as it is enabled by default.

* Breaking: the CLI option `--enable-multi-value=false` has been changed to
`--disable-multi-value` as it is enabled by default.

* Breaking: the CLI option `--enable-bulk-memory=false` has been changed to
`--disable-bulk-memory` as it is enabled by default.

* Modules serialized with `Module::serialize` can now be deserialized with
`Module::deserialize` on a compatible host that does not have to match the
original environment exactly.

## 0.25.0

Released 2021-03-16.
Expand Down Expand Up @@ -39,7 +68,7 @@ Released 2021-03-16.

### Fixed

* Interepretation of timestamps in `poll_oneoff` for WASI have been fixed to
* Interpretation of timestamps in `poll_oneoff` for WASI have been fixed to
correctly use nanoseconds instead of microseconds.
[#2717](https://github.com/bytecodealliance/wasmtime/pull/2717)

Expand Down
1 change: 1 addition & 0 deletions cranelift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ wasm = ["wat", "cranelift-wasm"]
experimental_x64 = ["cranelift-codegen/x64", "cranelift-filetests/experimental_x64", "cranelift-reader/experimental_x64"]
experimental_arm32 = ["cranelift-codegen/arm32", "cranelift-filetests/experimental_arm32"]
souper-harvest = ["cranelift-codegen/souper-harvest", "rayon"]
all-arch = ["cranelift-codegen/all-arch"]
68 changes: 68 additions & 0 deletions cranelift/codegen/meta/src/gen_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,72 @@ fn gen_constructor(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatte
fmtln!(fmt, "}");
}

/// Generates the `iter_enabled` function.
fn gen_iterator(group: &SettingGroup, fmt: &mut Formatter) {
fmtln!(fmt, "impl Flags {");
fmt.indent(|fmt| {
fmt.doc_comment("Iterates the enabled boolean settings.");
fmtln!(fmt, "pub fn iter_enabled(&self) -> impl Iterator<Item = &'static str> {");
fmt.indent(|fmt| {
fmtln!(fmt, "let mut bytes = [0; {}];", group.settings_size);
fmtln!(fmt, "bytes.copy_from_slice(&self.bytes[0..{}]);", group.settings_size);
fmtln!(fmt, "DESCRIPTORS.iter().filter_map(move |d| {");
fmt.indent(|fmt| {
fmtln!(fmt, "if match d.detail {");
fmt.indent(|fmt| {
fmtln!(fmt, "detail::Detail::Bool { bit } => (bytes[d.offset as usize] & (1 << bit as usize)) != 0,");
fmtln!(fmt, "_ => false");
});
fmtln!(fmt, "} {");
fmt.indent(|fmt| {
fmtln!(fmt, "Some(d.name)");
});
fmtln!(fmt, "} else {");
fmt.indent(|fmt| {
fmtln!(fmt, "None");
});
fmtln!(fmt, "}");
});
fmtln!(fmt, "})");
});
fmtln!(fmt, "}");
});
fmtln!(fmt, "}");
}

/// Generates the `is_enabled` function.
fn gen_is_enabled(fmt: &mut Formatter) {
fmtln!(fmt, "impl Flags {");
fmt.indent(|fmt| {
fmt.doc_comment("Checks if a boolean setting is enabled by name.");
fmtln!(fmt, "pub fn is_enabled(&self, name: &str) -> bool {");
fmt.indent(|fmt| {
fmtln!(fmt, "match crate::constant_hash::probe(&TEMPLATE, name, crate::constant_hash::simple_hash(name)) {");
fmt.indent(|fmt| {
fmtln!(fmt, "Err(_) => false,");
fmtln!(fmt, "Ok(entry) => {");
fmt.indent(|fmt| {
fmtln!(fmt, "let d = &TEMPLATE.descriptors[TEMPLATE.hash_table[entry] as usize];");
fmtln!(fmt, "match &d.detail {");
fmt.indent(|fmt| {
fmtln!(fmt, "detail::Detail::Bool{ bit } => {");
fmt.indent(|fmt| {
fmtln!(fmt, "(self.bytes[d.offset as usize] & (1 << bit)) != 0");
});
fmtln!(fmt, "},");
fmtln!(fmt, "_ => false");
});
fmtln!(fmt, "}");
});
fmtln!(fmt, "}");
});
fmtln!(fmt, "}");
});
fmtln!(fmt, "}");
});
fmtln!(fmt, "}");
}

/// Emit Display and FromStr implementations for enum settings.
fn gen_to_and_from_str(name: &str, values: &[&'static str], fmt: &mut Formatter) {
fmtln!(fmt, "impl fmt::Display for {} {{", name);
Expand Down Expand Up @@ -427,6 +493,8 @@ fn gen_group(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatter) {
fmtln!(fmt, "}");

gen_constructor(group, parent, fmt);
gen_iterator(group, fmt);
gen_is_enabled(fmt);
gen_enum_types(group, fmt);
gen_getters(group, fmt);
gen_descriptors(group, fmt);
Expand Down
3 changes: 3 additions & 0 deletions cranelift/codegen/meta/src/isa/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
use crate::shared::Definitions as SharedDefinitions;

fn define_settings(_shared: &SettingGroup) -> SettingGroup {
// Note: Wasmtime's `compile` command exposes these settings as CLI options
// If the settings change, please update src/commands/compile.rs to match.

let mut setting = SettingGroupBuilder::new("arm64");
let has_lse = setting.add_bool("has_lse", "Large System Extensions", false);

Expand Down
5 changes: 4 additions & 1 deletion cranelift/codegen/meta/src/isa/x86/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
pub(crate) fn define(shared: &SettingGroup) -> SettingGroup {
let mut settings = SettingGroupBuilder::new("x86");

// Note: Wasmtime's `compile` command exposes these settings as CLI options
// If the settings change, please update src/commands/compile.rs to match.

// CPUID.01H:ECX
let has_sse3 = settings.add_bool("has_sse3", "SSE3: CPUID.01H:ECX.SSE3[bit 0]", false);
let has_ssse3 = settings.add_bool("has_ssse3", "SSSE3: CPUID.01H:ECX.SSSE3[bit 9]", false);
Expand Down Expand Up @@ -85,7 +88,7 @@ pub(crate) fn define(shared: &SettingGroup) -> SettingGroup {
settings.add_predicate("use_lzcnt", predicate!(has_lzcnt));

// Some shared boolean values are used in x86 instruction predicates, so we need to group them
// in the same TargetIsa, for compabitibity with code generated by meta-python.
// in the same TargetIsa, for compatibility with code generated by meta-python.
// TODO Once all the meta generation code has been migrated from Python to Rust, we can put it
// back in the shared SettingGroup, and use it in x86 instruction predicates.

Expand Down
15 changes: 12 additions & 3 deletions cranelift/codegen/src/isa/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ use crate::isa::Builder as IsaBuilder;
use crate::machinst::{compile, MachBackend, MachCompileResult, TargetIsaAdapter, VCode};
use crate::result::CodegenResult;
use crate::settings as shared_settings;

use alloc::boxed::Box;
use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
use core::hash::{Hash, Hasher};

use regalloc::{PrettyPrint, RealRegUniverse};
use target_lexicon::{Aarch64Architecture, Architecture, Triple};

Expand Down Expand Up @@ -104,6 +102,17 @@ impl MachBackend for AArch64Backend {
&self.flags
}

fn enabled_isa_flags(&self) -> Vec<String> {
self.isa_flags
.iter_enabled()
.map(ToOwned::to_owned)
.collect()
}

fn is_flag_enabled(&self, flag: &str) -> bool {
self.isa_flags.is_enabled(flag)
}

fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.flags.hash(&mut hasher);
self.isa_flags.hash(&mut hasher);
Expand Down
10 changes: 9 additions & 1 deletion cranelift/codegen/src/isa/arm32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::machinst::{compile, MachBackend, MachCompileResult, TargetIsaAdapter,
use crate::result::CodegenResult;
use crate::settings;

use alloc::boxed::Box;
use alloc::{boxed::Box, string::String, vec::Vec};
use core::hash::{Hash, Hasher};
use regalloc::{PrettyPrint, RealRegUniverse};
use target_lexicon::{Architecture, ArmArchitecture, Triple};
Expand Down Expand Up @@ -92,6 +92,14 @@ impl MachBackend for Arm32Backend {
&self.flags
}

fn enabled_isa_flags(&self) -> Vec<String> {
Vec::new()
}

fn is_flag_enabled(&self, _flag: &str) -> bool {
false
}

fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.flags.hash(&mut hasher);
}
Expand Down
12 changes: 8 additions & 4 deletions cranelift/codegen/src/isa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ use crate::result::CodegenResult;
use crate::settings;
use crate::settings::SetResult;
use crate::timing;
use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
use core::any::Any;
use core::fmt;
use core::fmt::{Debug, Formatter};
Expand Down Expand Up @@ -265,8 +264,13 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
/// Get the ISA-independent flags that were used to make this trait object.
fn flags(&self) -> &settings::Flags;

/// Hashes all flags, both ISA-independent and ISA-specific, into the
/// specified hasher.
/// Get the enabled ISA-dependent flags that were used to make this trait object.
fn enabled_isa_flags(&self) -> Vec<String>;

/// Determines if the given ISA-dependent flag is enabled.
fn is_flag_enabled(&self, flag: &str) -> bool;

/// Hashes all flags, both ISA-independent and ISA-dependent, into the specified hasher.
fn hash_all_flags(&self, hasher: &mut dyn Hasher);

/// Get the default calling convention of this target.
Expand Down
19 changes: 17 additions & 2 deletions cranelift/codegen/src/isa/riscv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ use crate::isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encoding
use crate::isa::Builder as IsaBuilder;
use crate::isa::{EncInfo, RegClass, RegInfo, TargetIsa};
use crate::regalloc;
use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::{
borrow::{Cow, ToOwned},
boxed::Box,
string::String,
vec::Vec,
};
use core::any::Any;
use core::fmt;
use core::hash::{Hash, Hasher};
Expand Down Expand Up @@ -70,6 +74,17 @@ impl TargetIsa for Isa {
&self.shared_flags
}

fn enabled_isa_flags(&self) -> Vec<String> {
self.isa_flags
.iter_enabled()
.map(ToOwned::to_owned)
.collect()
}

fn is_flag_enabled(&self, flag: &str) -> bool {
self.isa_flags.is_enabled(flag)
}

fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.shared_flags.hash(&mut hasher);
self.isa_flags.hash(&mut hasher);
Expand Down
13 changes: 12 additions & 1 deletion cranelift/codegen/src/isa/x64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::isa::Builder as IsaBuilder;
use crate::machinst::{compile, MachBackend, MachCompileResult, TargetIsaAdapter, VCode};
use crate::result::CodegenResult;
use crate::settings::{self as shared_settings, Flags};
use alloc::boxed::Box;
use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
use core::hash::{Hash, Hasher};
use regalloc::{PrettyPrint, RealRegUniverse, Reg};
use target_lexicon::Triple;
Expand Down Expand Up @@ -85,6 +85,17 @@ impl MachBackend for X64Backend {
&self.flags
}

fn enabled_isa_flags(&self) -> Vec<String> {
self.x64_flags
.iter_enabled()
.map(ToOwned::to_owned)
.collect()
}

fn is_flag_enabled(&self, flag: &str) -> bool {
self.x64_flags.is_enabled(flag)
}

fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.flags.hash(&mut hasher);
self.x64_flags.hash(&mut hasher);
Expand Down
19 changes: 17 additions & 2 deletions cranelift/codegen/src/isa/x86/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ use crate::isa::{EncInfo, RegClass, RegInfo, TargetIsa};
use crate::regalloc;
use crate::result::CodegenResult;
use crate::timing;
use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::{
borrow::{Cow, ToOwned},
boxed::Box,
string::String,
vec::Vec,
};
use core::any::Any;
use core::fmt;
use core::hash::{Hash, Hasher};
Expand Down Expand Up @@ -79,6 +83,17 @@ impl TargetIsa for Isa {
&self.shared_flags
}

fn enabled_isa_flags(&self) -> Vec<String> {
self.isa_flags
.iter_enabled()
.map(ToOwned::to_owned)
.collect()
}

fn is_flag_enabled(&self, flag: &str) -> bool {
self.isa_flags.is_enabled(flag)
}

fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) {
self.shared_flags.hash(&mut hasher);
self.isa_flags.hash(&mut hasher);
Expand Down
11 changes: 9 additions & 2 deletions cranelift/codegen/src/machinst/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use crate::regalloc::RegDiversions;
use crate::isa::unwind::systemv::RegisterMappingError;

use core::any::Any;
use core::hash::Hasher;
use std::borrow::Cow;
use std::fmt;
use target_lexicon::Triple;
Expand Down Expand Up @@ -59,8 +58,16 @@ impl TargetIsa for TargetIsaAdapter {
self.backend.flags()
}

fn enabled_isa_flags(&self) -> Vec<String> {
self.backend.enabled_isa_flags()
}

fn is_flag_enabled(&self, flag: &str) -> bool {
self.backend.is_flag_enabled(flag)
}

fn hash_all_flags(&self, hasher: &mut dyn Hasher) {
self.backend.hash_all_flags(hasher)
self.backend.hash_all_flags(hasher);
}

fn register_info(&self) -> RegInfo {
Expand Down
11 changes: 8 additions & 3 deletions cranelift/codegen/src/machinst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ use crate::value_label::ValueLabelsRanges;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::fmt::Debug;
use core::hash::Hasher;
use cranelift_entity::PrimaryMap;
use regalloc::RegUsageCollector;
use regalloc::{
RealReg, RealRegUniverse, Reg, RegClass, RegUsageMapper, SpillSlot, VirtualReg, Writable,
};
use smallvec::{smallvec, SmallVec};
use std::hash::Hasher;
use std::string::String;
use target_lexicon::Triple;

Expand Down Expand Up @@ -368,8 +368,13 @@ pub trait MachBackend {
/// Return flags for this backend.
fn flags(&self) -> &Flags;

/// Hashes all flags, both ISA-independent and ISA-specific, into the
/// specified hasher.
/// Get the enabled ISA-dependent flags that were used to make this trait object.
fn enabled_isa_flags(&self) -> Vec<String>;

/// Determines if the given ISA-dependent flag is enabled.
fn is_flag_enabled(&self, flag: &str) -> bool;

/// Hashes all flags, both ISA-independent and ISA-dependent, into the specified hasher.
fn hash_all_flags(&self, hasher: &mut dyn Hasher);

/// Return triple for this backend.
Expand Down
Loading

0 comments on commit ccb58e1

Please sign in to comment.