Skip to content

Commit

Permalink
wasmparser: feature gate Wasm simd support (#1903)
Browse files Browse the repository at this point in the history
* add for_each_simd_operator generator macro

* define SimdOperator enum

* add SimdOperator::operator_arity impl

* add VisitSimdOperator trait definition

* define VisitSimdOperator delegates

* add benchmark NopVisit impl

* add simd crate feature

* add simd_visitor method to VisitOperator trait

* add VisitSimdOperator impl to OperatorFactory

* use VisitOperator::simd_visitor in BinaryReader::visit_operator

* add lifetime to return value of simd_visitor method

* add VisitSimdOperator impl for OperatorValidator

* add Operator::Simd variant

* remove simd operators from for_each_operator macro

* adjust wasmprinter crate for simd crate feature

* enable wasmparser's simd feature by default

* fix trait impl signature

* add docs to wasmparser's simd crate feature

* feature gate simd related code in wasmparser

* update docs for SimdOperator

* add missing `simd` crate feature gates

* move simd op validation down in file

* put simd specific operator validation in separate file

* add docs to for_each_simd_operator macro

* move for_each_simd_operator macro into a separate file

* fix docs for VisitSimdOperator

* allow missing docs again for VisitSimdOperator

This is just like with VisitOperator trait.

* add docs and example to VisitOperator::simd_visitor

* move visit_0xfd_operator into separate file

We do this to further improve compile times for when the `simd` crate feature is disabled.

* apply rustftm

* wasmprinter: fix remaining simd feature toggles

* apply rustfmt

* fix wasmparser benchmarks

* wasm-encoder: add simd support

* apply rustfmt and avoid formatting some parts

* wasm-mutate: fix compile errors

* apply rustfmt

* fix dev-dependencies for wasm-mutate

* add simd_visitor impl to NopVisitor

* add missing VisitSimdOperator impl for WasmProposalValidator

* mark doc example as compile_fail

* add simd support for VisitConstOperator

* use wasmparser/simd in validate tool

* add simd crate feature propagation to wasm-tools CLI tool

* wasm-smith: use wasmparser/simd crate feature

* apply rustfmt

* feature gate simd_visitor impl

* unconditionally enable simd for wasmprinter

* unconditionally enable simd for wasm-encoder

* remove wasm-tools simd feature (enable by default)

* use macros generate for_each_operator macros

- This does not yet provide a for_each_operator macro in for !simd mode but that should be easily added.
- This is WIP in that is currently does not handle the documentation of the macros well. We might need to also generate the macro docs in the macros themselves.

* remove comment out line

* put docs on the exported macros

* fix macro imports

* fix bugs in generator macros

* improve compile times for macros

* group macro operators together

* restructure for_each_operator macros

This improves compile times performance significantly.

* apply rustfmt

* re-structure the new exposed macros

The wasmparser crate now exposes 3 different for_each macros:

- for_each_operator: Same as before the PR. Iterates over _all_ operators. This is going to be used to implement a routine for all Operator enum variants.
- for_each_visit_oeprator: This is going to be used to implement the `VisitOperator` trait.
- for_each_visit_simd_operator: This is going to be used to implement the `VisitSimdOperator` trait.

* fix macro doc links

* fix broken doc links

* fix crate after making Operator enum inline

* export all internal macro (debug)

* wasmprinter: use for_each_[visit[_simd]]_operator

* wasm-encoder: use simd feature in dependencies

* fix wasm-encoder compilation

* wasmparser: use macros via crate:: namespace

* expose macros via use statements

* use doc(inline)

* use intra-doc links

* wit-component: fix wasmparser usage

* wasm-mutate: fix wasmparser usage

This mostly reverts the changes done in past commits of the PR.

* wasm-dump: fix wasmparser usage

* wasmparser: fix benchmarks

* fix doc tests

* change doc example for for_each_operator macro

* rename doc test macro

* fix typo

* apply rustfmt

* craft new doc example for for_each_operator! macro

* Minor changes

* Revert `crates/wasm-encoder/src/reencode.rs` back to `main` version
  (no changes needed any more)
* Minor whitespace/style changes
* Document the macros some more in `wasmparser/src/lib.rs`
* Reorganize macro-defining-macros to have more predictable names.

* A few more minor adjustments

---------

Co-authored-by: Alex Crichton <[email protected]>
  • Loading branch information
Robbepop and alexcrichton authored Nov 26, 2024
1 parent d9ca220 commit c0eab4d
Show file tree
Hide file tree
Showing 20 changed files with 2,529 additions and 1,987 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ wasm-metadata = { version = "0.220.0", path = "crates/wasm-metadata" }
wasm-mutate = { version = "0.220.0", path = "crates/wasm-mutate" }
wasm-shrink = { version = "0.220.0", path = "crates/wasm-shrink" }
wasm-smith = { version = "0.220.0", path = "crates/wasm-smith" }
wasmparser = { version = "0.220.0", path = "crates/wasmparser", default-features = false, features = ['std'] }
wasmparser = { version = "0.220.0", path = "crates/wasmparser", default-features = false, features = ['std','simd'] }
wasmprinter = { version = "0.220.0", path = "crates/wasmprinter", default-features = false }
wast = { version = "220.0.0", path = "crates/wast", default-features = false }
wat = { version = "1.220.0", path = "crates/wat", default-features = false }
Expand All @@ -122,7 +122,7 @@ wat = { workspace = true, features = ['dwarf', 'component-model'] }
termcolor = { workspace = true }

# Dependencies of `validate`
wasmparser = { workspace = true, optional = true, features = ['component-model'] }
wasmparser = { workspace = true, optional = true, features = ['component-model', 'simd'] }
rayon = { workspace = true, optional = true }
bitflags = { workspace = true, optional = true }

Expand Down
2 changes: 1 addition & 1 deletion crates/wasm-encoder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ leb128 = { workspace = true }

# Enable this dependency to get a bunch of `From<wasmparser::Foo> for
# wasm_encoder::Foo` impls.
wasmparser = { optional = true, workspace = true }
wasmparser = { optional = true, workspace = true, features = ["simd"] }

[dev-dependencies]
anyhow = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions crates/wasm-encoder/src/reencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,7 @@ pub mod utils {
translate!(build $op $($($arg)*)?)
}
)*
unexpected => unreachable!("encountered unexpected Wasm operator: {unexpected:?}"),
})
};

Expand Down
6 changes: 3 additions & 3 deletions crates/wasm-mutate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ workspace = true
[dependencies]
clap = { workspace = true, optional = true }
thiserror = "1.0.28"
wasmparser = { workspace = true }
wasm-encoder = { workspace = true, features = ["wasmparser"] }
wasmparser = { workspace = true, features = ['simd'] }
wasm-encoder = { workspace = true, features = ['wasmparser'] }
rand = { workspace = true }
log = { workspace = true }
egg = "0.6.0"
Expand All @@ -24,4 +24,4 @@ anyhow = { workspace = true }
wat = { workspace = true }
wasmprinter = { workspace = true }
env_logger = { workspace = true }
wasmparser = { workspace = true, features = ['validate', 'features'] }
wasmparser = { workspace = true, features = ['validate', 'features', 'simd'] }
4 changes: 2 additions & 2 deletions crates/wasm-smith/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ leb128 = { workspace = true }
serde = { workspace = true, optional = true }
serde_derive = { workspace = true, optional = true }
wasm-encoder = { workspace = true }
wasmparser = { workspace = true, optional = true, features = ['validate', 'features'] }
wasmparser = { workspace = true, optional = true, features = ['validate', 'features', 'simd'] }
wat = { workspace = true, optional = true }

[dev-dependencies]
criterion = { workspace = true }
rand = { workspace = true }
wasmparser = { workspace = true, features = ["validate", "features"] }
wasmparser = { workspace = true, features = ['validate', 'features', 'simd'] }
wasmprinter = { workspace = true }
wat = { workspace = true }

Expand Down
7 changes: 6 additions & 1 deletion crates/wasmparser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ name = "benchmark"
harness = false

[features]
default = ['std', 'validate', 'serde', 'features', 'component-model', 'hash-collections']
default = ['std', 'validate', 'serde', 'features', 'component-model', 'hash-collections', 'simd']

# A feature which enables implementations of `std::error::Error` as appropriate
# along with other convenience APIs. This additionally uses the standard
Expand Down Expand Up @@ -82,3 +82,8 @@ features = []
# WebAssembly. This is enabled by default but if your use case is only
# interested in working with core modules then this feature can be disabled.
component-model = ['dep:semver']

# A feature that enables parsing and validating the `simd` and `relaxed-simd`
# proposals for WebAssembly. This is enabled by default but if your use case is
# only interested in working on non-SIMD code then this feature can be disabled.
simd = []
12 changes: 11 additions & 1 deletion crates/wasmparser/benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use once_cell::unsync::Lazy;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use wasmparser::VisitSimdOperator;
use wasmparser::{DataKind, ElementKind, Parser, Payload, Validator, VisitOperator, WasmFeatures};

/// A benchmark input.
Expand Down Expand Up @@ -364,5 +365,14 @@ macro_rules! define_visit_operator {
impl<'a> VisitOperator<'a> for NopVisit {
type Output = ();

wasmparser::for_each_operator!(define_visit_operator);
fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> {
Some(self)
}

wasmparser::for_each_visit_operator!(define_visit_operator);
}

#[allow(unused_variables)]
impl<'a> VisitSimdOperator<'a> for NopVisit {
wasmparser::for_each_visit_simd_operator!(define_visit_operator);
}
2 changes: 1 addition & 1 deletion crates/wasmparser/src/arity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,6 @@ impl Operator<'_> {
}
);
}
for_each_operator!(define_arity)
crate::for_each_operator!(define_arity)
}
}
Loading

0 comments on commit c0eab4d

Please sign in to comment.