Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a compile command to Wasmtime. #2791

Merged
merged 12 commits into from
Apr 2, 2021
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ anyhow = "1.0.19"
target-lexicon = { version = "0.12.0", default-features = false }
pretty_env_logger = "0.4.0"
file-per-thread-logger = "0.1.1"
wat = "1.0.36"
wat = "1.0.37"
libc = "0.2.60"
log = "0.4.8"
rayon = "1.2.1"
humantime = "2.0.0"
wasmparser = "0.77.0"
lazy_static = "1.4.0"

[dev-dependencies]
env_logger = "0.8.1"
Expand Down Expand Up @@ -90,6 +91,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
43 changes: 42 additions & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,47 @@

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

## Unreleased

### Added

* Added the `wasmtime compile` command to support AOT compilation of Wasm modules.

* Added the `Engine::precompile_module` method to support AOT module compilation.

* Added the `Config::target` method to change the compilation target of the
configuration. This can be used in conjunction with `Engine::precompile_module`
to target a different host triple than the current one.

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

* Added CLI option `--cranelift-enable` to enable boolean settings and ISA presets.

### Changed

* Wasmtime CLI options to enable WebAssembly features have been replaced with a
singular `--wasm-features` option. The previous options are still supported, but
are not displayed in help text.

* Breaking: `Module::deserialize` has been removed in favor of `Module::new`.

* Breaking: `Config::cranelift_clear_cpu_flags` was removed. Use `Config::target`
to clear the CPU flags for the host's target.

* Breaking: `Config::cranelift_other_flag` was renamed to `Config::cranelift_flag_set`.

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

* Breaking: the CLI option `--enable-reference-types=false` has been changed to
`--wasm-features=-reference-types`.

* Breaking: the CLI option `--enable-multi-value=false` has been changed to
`--wasm-features=-multi-value`.

* Breaking: the CLI option `--enable-bulk-memory=false` has been changed to
`--wasm-features=-bulk-memory`.

## 0.25.0

Released 2021-03-16.
Expand Down Expand Up @@ -39,7 +80,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"]
51 changes: 45 additions & 6 deletions cranelift/codegen/meta/src/cdsl/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub(crate) enum SpecificSetting {
#[derive(Hash, PartialEq, Eq)]
pub(crate) struct Setting {
pub name: &'static str,
pub description: &'static str,
pub comment: &'static str,
pub specific: SpecificSetting,
pub byte_offset: u8,
Expand Down Expand Up @@ -88,6 +89,7 @@ impl Into<PresetType> for PresetIndex {
#[derive(Hash, PartialEq, Eq)]
pub(crate) struct Preset {
pub name: &'static str,
pub description: &'static str,
values: Vec<BoolSettingIndex>,
}

Expand Down Expand Up @@ -169,6 +171,7 @@ pub(crate) enum ProtoSpecificSetting {
/// This is the information provided during building for a setting.
struct ProtoSetting {
name: &'static str,
description: &'static str,
comment: &'static str,
specific: ProtoSpecificSetting,
}
Expand Down Expand Up @@ -251,11 +254,13 @@ impl SettingGroupBuilder {
fn add_setting(
&mut self,
name: &'static str,
description: &'static str,
comment: &'static str,
specific: ProtoSpecificSetting,
) {
self.settings.push(ProtoSetting {
name,
description,
comment,
specific,
})
Expand All @@ -264,35 +269,63 @@ impl SettingGroupBuilder {
pub fn add_bool(
&mut self,
name: &'static str,
description: &'static str,
comment: &'static str,
default: bool,
) -> BoolSettingIndex {
assert!(
self.predicates.is_empty(),
"predicates must be added after the boolean settings"
);
self.add_setting(name, comment, ProtoSpecificSetting::Bool(default));
self.add_setting(
name,
description,
comment,
ProtoSpecificSetting::Bool(default),
);
BoolSettingIndex(self.settings.len() - 1)
}

pub fn add_enum(
&mut self,
name: &'static str,
description: &'static str,
comment: &'static str,
values: Vec<&'static str>,
) {
self.add_setting(name, comment, ProtoSpecificSetting::Enum(values));
self.add_setting(
name,
description,
comment,
ProtoSpecificSetting::Enum(values),
);
}

pub fn add_num(&mut self, name: &'static str, comment: &'static str, default: u8) {
self.add_setting(name, comment, ProtoSpecificSetting::Num(default));
pub fn add_num(
&mut self,
name: &'static str,
description: &'static str,
comment: &'static str,
default: u8,
) {
self.add_setting(
name,
description,
comment,
ProtoSpecificSetting::Num(default),
);
}

pub fn add_predicate(&mut self, name: &'static str, node: PredicateNode) {
self.predicates.push(ProtoPredicate { name, node });
}

pub fn add_preset(&mut self, name: &'static str, args: Vec<PresetType>) -> PresetIndex {
pub fn add_preset(
&mut self,
name: &'static str,
description: &'static str,
args: Vec<PresetType>,
) -> PresetIndex {
let mut values = Vec::new();
for arg in args {
match arg {
Expand All @@ -302,7 +335,11 @@ impl SettingGroupBuilder {
PresetType::BoolSetting(index) => values.push(index),
}
}
self.presets.push(Preset { name, values });
self.presets.push(Preset {
name,
description,
values,
});
PresetIndex(self.presets.len() - 1)
}

Expand Down Expand Up @@ -347,6 +384,7 @@ impl SettingGroupBuilder {

group.settings.push(Setting {
name: s.name,
description: s.description,
comment: s.comment,
byte_offset,
specific,
Expand All @@ -367,6 +405,7 @@ impl SettingGroupBuilder {
};
group.settings.push(Setting {
name: s.name,
description: s.description,
comment: s.comment,
byte_offset: byte_offset + predicate_number / 8,
specific: SpecificSetting::Bool(BoolSetting {
Expand Down
32 changes: 31 additions & 1 deletion cranelift/codegen/meta/src/gen_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,33 @@ fn gen_constructor(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatte
fmtln!(fmt, "}");
}

/// Generates the `iter` function.
fn gen_iterator(group: &SettingGroup, fmt: &mut Formatter) {
fmtln!(fmt, "impl Flags {");
fmt.indent(|fmt| {
fmt.doc_comment("Iterates the setting values.");
fmtln!(fmt, "pub fn iter(&self) -> impl Iterator<Item = Value> {");
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, "let values = match &d.detail {");
fmt.indent(|fmt| {
fmtln!(fmt, "detail::Detail::Preset => return None,");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One possible backwards-compatibility consideration: it looks like this will result in no encoding of default options in the saved compiled module, but if we later change a default in an incompatible way, would we want to catch that?

(It's entirely possible that this is made irrelevant by some other versioning -- do you encode e.g. a git hash or wasmtime version in the .cwasm file too?)

Copy link
Member Author

@peterhuene peterhuene Apr 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that there are way too many ways incompatibilities can be introduced, so to combat that we do indeed record the crate version in the cwasm and must be an identical match for now (similar to the preexisting requirement for the code cache).

fmtln!(fmt, "detail::Detail::Enum { last, enumerators } => Some(TEMPLATE.enums(*last, *enumerators)),");
fmtln!(fmt, "_ => None");
});
fmtln!(fmt, "};");
fmtln!(fmt, "Some(Value{ name: d.name, detail: d.detail, values, value: bytes[d.offset as usize] })");
});
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 @@ -136,7 +163,7 @@ fn gen_enum_types(group: &SettingGroup, fmt: &mut Formatter) {

/// Emit a getter function for `setting`.
fn gen_getter(setting: &Setting, fmt: &mut Formatter) {
fmt.doc_comment(setting.comment);
fmt.doc_comment(format!("{}\n{}", setting.description, setting.comment));
match setting.specific {
SpecificSetting::Bool(BoolSetting {
predicate_number, ..
Expand Down Expand Up @@ -254,6 +281,7 @@ fn gen_descriptors(group: &SettingGroup, fmt: &mut Formatter) {
fmtln!(fmt, "detail::Descriptor {");
fmt.indent(|fmt| {
fmtln!(fmt, "name: \"{}\",", setting.name);
fmtln!(fmt, "description: \"{}\",", setting.description);
fmtln!(fmt, "offset: {},", setting.byte_offset);
match setting.specific {
SpecificSetting::Bool(BoolSetting { bit_offset, .. }) => {
Expand Down Expand Up @@ -286,6 +314,7 @@ fn gen_descriptors(group: &SettingGroup, fmt: &mut Formatter) {
fmtln!(fmt, "detail::Descriptor {");
fmt.indent(|fmt| {
fmtln!(fmt, "name: \"{}\",", preset.name);
fmtln!(fmt, "description: \"{}\",", preset.description);
fmtln!(fmt, "offset: {},", (idx as u8) * group.settings_size);
fmtln!(fmt, "detail: detail::Detail::Preset,");
});
Expand Down Expand Up @@ -427,6 +456,7 @@ fn gen_group(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatter) {
fmtln!(fmt, "}");

gen_constructor(group, parent, fmt);
gen_iterator(group, fmt);
gen_enum_types(group, fmt);
gen_getters(group, fmt);
gen_descriptors(group, fmt);
Expand Down
2 changes: 1 addition & 1 deletion cranelift/codegen/meta/src/isa/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::shared::Definitions as SharedDefinitions;

fn define_settings(_shared: &SettingGroup) -> SettingGroup {
let mut setting = SettingGroupBuilder::new("arm64");
let has_lse = setting.add_bool("has_lse", "Large System Extensions", false);
let has_lse = setting.add_bool("has_lse", "Has Large System Extensions support.", "", false);

setting.add_predicate("use_lse", predicate!(has_lse));
setting.build()
Expand Down
6 changes: 6 additions & 0 deletions cranelift/codegen/meta/src/isa/riscv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,39 @@ fn define_settings(shared: &SettingGroup) -> SettingGroup {
let supports_m = setting.add_bool(
"supports_m",
"CPU supports the 'M' extension (mul/div)",
"",
false,
);
let supports_a = setting.add_bool(
"supports_a",
"CPU supports the 'A' extension (atomics)",
"",
false,
);
let supports_f = setting.add_bool(
"supports_f",
"CPU supports the 'F' extension (float)",
"",
false,
);
let supports_d = setting.add_bool(
"supports_d",
"CPU supports the 'D' extension (double)",
"",
false,
);

let enable_m = setting.add_bool(
"enable_m",
"Enable the use of 'M' instructions if available",
"",
true,
);

setting.add_bool(
"enable_e",
"Enable the 'RV32E' instruction set with only 16 registers",
"",
false,
);

Expand Down
Loading