Skip to content

Commit f2f7b31

Browse files
committed
wasmparser: merge VisitSimdOperator back into VisitOperator
The `simd` feature remains in place, but now does not affect the API in this way. Rather parts of implementation pertaining to SIMD in wasmparser get disabled, reducing the compilation time and artifact size impact slightly, though less than in the original approach. The results on my machine are roughly: * origin/main simd: 4.26s producing 30M .rlib * origin/main !simd: 3.49s producing 23M .rlib * this simd: 4.19s producing a 26M .rlib * this !simd: 3.96s producing a 25M .rlib I'm not quite sure why the rlib size decreased so significantly when the SIMD feature is enabled (I guess less inlining is occurring?) and there is indeed a .5s hit on the compilation time to this PR. Are those half a second worth a clunkier API? I'm not convinced :)
1 parent b0d1dd7 commit f2f7b31

File tree

9 files changed

+755
-898
lines changed

9 files changed

+755
-898
lines changed

crates/wasmparser/src/lib.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -827,21 +827,14 @@ macro_rules! define_for_each_non_simd_operator {
827827
$m! { $($t)* }
828828
}
829829
}
830-
831-
// When simd is disabled then this macro is additionally the
832-
// `for_each_operator!` macro implementation
833-
#[cfg(not(feature = "simd"))]
834-
#[doc(hidden)]
835-
pub use _for_each_visit_operator_impl as _for_each_operator_impl;
836830
};
837831
}
838832
_for_each_operator_group!(define_for_each_non_simd_operator);
839833

840834
/// When the simd feature is enabled then `_for_each_operator_impl` is defined
841835
/// to be the same as the above `define_for_each_non_simd_operator` macro except
842836
/// with all proposals thrown in.
843-
#[cfg(feature = "simd")]
844-
macro_rules! define_for_each_operator_impl_with_simd {
837+
macro_rules! define_for_each_operator_impl {
845838
(
846839
$(
847840
@$proposal:ident {
@@ -864,14 +857,12 @@ macro_rules! define_for_each_operator_impl_with_simd {
864857
}
865858
};
866859
}
867-
#[cfg(feature = "simd")]
868-
_for_each_operator_group!(define_for_each_operator_impl_with_simd);
860+
_for_each_operator_group!(define_for_each_operator_impl);
869861

870862
/// Helper macro to define the `_for_each_simd_operator_impl` macro.
871863
///
872864
/// This is basically the same as `define_for_each_non_simd_operator` above
873865
/// except that it's filtering on different proposals.
874-
#[cfg(feature = "simd")]
875866
macro_rules! define_for_each_simd_operator {
876867
// Switch to "tt muncher" mode
877868
(@ $($t:tt)*) => {define_for_each_simd_operator!(filter [] @ $($t)*);};
@@ -924,7 +915,7 @@ macro_rules! define_for_each_simd_operator {
924915
}
925916
};
926917
}
927-
#[cfg(feature = "simd")]
918+
928919
_for_each_operator_group!(define_for_each_simd_operator);
929920

930921
/// Used to implement routines for the [`Operator`] enum.
@@ -1272,7 +1263,6 @@ pub use _for_each_visit_operator_impl as for_each_visit_operator;
12721263
/// wasmparser::for_each_visit_simd_operator!(define_visit_simd_operator);
12731264
/// }
12741265
/// ```
1275-
#[cfg(feature = "simd")]
12761266
#[doc(inline)]
12771267
pub use _for_each_visit_simd_operator_impl as for_each_visit_simd_operator;
12781268

crates/wasmparser/src/readers/core/operators.rs

Lines changed: 315 additions & 407 deletions
Large diffs are not rendered by default.

crates/wasmparser/src/validator/core.rs

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ use super::{
1010
operators::{ty_to_str, OperatorValidator, OperatorValidatorAllocations},
1111
types::{CoreTypeId, EntityType, RecGroupId, TypeAlloc, TypeList},
1212
};
13-
#[cfg(feature = "simd")]
14-
use crate::VisitSimdOperator;
1513
use crate::{
1614
limits::*, BinaryReaderError, ConstExpr, Data, DataKind, Element, ElementKind, ExternalKind,
1715
FuncType, Global, GlobalType, HeapType, MemoryType, RecGroup, RefType, Result, SubType, Table,
@@ -234,6 +232,15 @@ impl ModuleState {
234232
self.ops.with_resources(&self.resources, self.offset)
235233
}
236234

235+
#[cold]
236+
#[cfg(not(feature = "simd"))]
237+
fn simd_unavailable(&mut self) -> Result<()> {
238+
Err(BinaryReaderError::new(
239+
format!("SIMD not enabled at compile time"),
240+
self.offset,
241+
))
242+
}
243+
237244
fn validate_extended_const(&mut self, op: &str) -> Result<()> {
238245
if self.ops.features.extended_const() {
239246
Ok(())
@@ -326,12 +333,28 @@ impl ModuleState {
326333
#[cfg_attr(not(feature = "simd"), allow(unused_macro_rules))]
327334
macro_rules! define_visit_operator {
328335
($(@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
329-
$(
330-
#[allow(unused_variables)]
331-
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
332-
define_visit_operator!(@visit self $visit $($($arg)*)?)
333-
}
334-
)*
336+
$(define_visit_operator!(expand @$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*));)*
337+
};
338+
339+
(expand @simd $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => {
340+
#[cfg(not(feature = "simd"))]
341+
#[allow(unused_variables)]
342+
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
343+
self.simd_unavailable()
344+
}
345+
346+
#[cfg(feature = "simd")]
347+
#[allow(unused_variables)]
348+
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
349+
define_visit_operator!(@visit self $visit $($($arg)*)?)
350+
}
351+
};
352+
353+
(expand @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => {
354+
#[allow(unused_variables)]
355+
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
356+
define_visit_operator!(@visit self $visit $($($arg)*)?)
357+
}
335358
};
336359

337360
// These are always valid in const expressions
@@ -348,7 +371,7 @@ impl ModuleState {
348371
$self.validator().visit_f64_const($val)
349372
}};
350373
(@visit $self:ident visit_v128_const $val:ident) => {{
351-
$self.validator().simd_visitor().unwrap().visit_v128_const($val)
374+
$self.validator().visit_v128_const($val)
352375
}};
353376
(@visit $self:ident visit_ref_null $val:ident) => {{
354377
$self.validator().visit_ref_null($val)
@@ -444,18 +467,7 @@ impl ModuleState {
444467
impl<'a> VisitOperator<'a> for VisitConstOperator<'a> {
445468
type Output = Result<()>;
446469

447-
#[cfg(feature = "simd")]
448-
fn simd_visitor(
449-
&mut self,
450-
) -> Option<&mut dyn crate::VisitSimdOperator<'a, Output = Self::Output>> {
451-
Some(self)
452-
}
453-
454470
crate::for_each_visit_operator!(define_visit_operator);
455-
}
456-
457-
#[cfg(feature = "simd")]
458-
impl<'a> VisitSimdOperator<'a> for VisitConstOperator<'a> {
459471
crate::for_each_visit_simd_operator!(define_visit_operator);
460472
}
461473
}

crates/wasmparser/src/validator/func.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,6 @@ impl<T: WasmModuleResources> FuncValidator<T> {
176176
self.validator.with_resources(&self.resources, offset)
177177
}
178178

179-
/// Same as [`FuncValidator::visitor`] except that the returned type
180-
/// implements the [`VisitSimdOperator`](crate::VisitSimdOperator) trait as
181-
/// well.
182-
#[cfg(feature = "simd")]
183-
pub fn simd_visitor<'this, 'a: 'this>(
184-
&'this mut self,
185-
offset: usize,
186-
) -> impl crate::VisitSimdOperator<'a, Output = Result<()>> + ModuleArity + 'this {
187-
self.validator.with_resources_simd(&self.resources, offset)
188-
}
189-
190179
/// Returns the Wasm features enabled for this validator.
191180
pub fn features(&self) -> &WasmFeatures {
192181
&self.validator.features

crates/wasmparser/src/validator/operators.rs

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
// confusing it's recommended to read over that section to see how it maps to
2323
// the various methods here.
2424

25-
#[cfg(feature = "simd")]
26-
use crate::VisitSimdOperator;
2725
use crate::{
2826
limits::MAX_WASM_FUNCTION_LOCALS, AbstractHeapType, BinaryReaderError, BlockType, BrTable,
2927
Catch, ContType, FieldType, FrameKind, FuncType, GlobalType, Handle, HeapType, Ieee32, Ieee64,
@@ -488,25 +486,6 @@ impl OperatorValidator {
488486
})
489487
}
490488

491-
/// Same as `with_resources` above but guarantees it's able to visit simd
492-
/// operators as well.
493-
#[cfg(feature = "simd")]
494-
pub fn with_resources_simd<'a, 'validator, 'resources, T>(
495-
&'validator mut self,
496-
resources: &'resources T,
497-
offset: usize,
498-
) -> impl VisitSimdOperator<'a, Output = Result<()>> + ModuleArity + 'validator
499-
where
500-
T: WasmModuleResources,
501-
'resources: 'validator,
502-
{
503-
WasmProposalValidator(OperatorValidatorTemp {
504-
offset,
505-
inner: self,
506-
resources,
507-
})
508-
}
509-
510489
pub fn into_allocations(mut self) -> OperatorValidatorAllocations {
511490
fn clear<T>(mut tmp: Vec<T>) -> Vec<T> {
512491
tmp.clear();
@@ -998,6 +977,12 @@ where
998977
Ok(())
999978
}
1000979

980+
#[cold]
981+
#[cfg(not(feature = "simd"))]
982+
fn simd_unavailable(&self) -> Result<()> {
983+
bail!(self.offset, "SIMD not compiled-in");
984+
}
985+
1001986
fn check_shared_memarg(&self, memarg: MemArg) -> Result<ValType> {
1002987
if memarg.align != memarg.max_align {
1003988
bail!(
@@ -1693,7 +1678,6 @@ impl<T> WasmProposalValidator<'_, '_, T> {
16931678
}
16941679
}
16951680

1696-
#[cfg_attr(not(feature = "simd"), allow(unused_macro_rules))]
16971681
macro_rules! validate_proposal {
16981682
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
16991683
$(
@@ -1732,21 +1716,7 @@ where
17321716
T: WasmModuleResources,
17331717
{
17341718
type Output = Result<()>;
1735-
1736-
#[cfg(feature = "simd")]
1737-
fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> {
1738-
Some(self)
1739-
}
1740-
1741-
crate::for_each_visit_operator!(validate_proposal);
1742-
}
1743-
1744-
#[cfg(feature = "simd")]
1745-
impl<'a, T> VisitSimdOperator<'a> for WasmProposalValidator<'_, '_, T>
1746-
where
1747-
T: WasmModuleResources,
1748-
{
1749-
crate::for_each_visit_simd_operator!(validate_proposal);
1719+
crate::for_each_operator!(validate_proposal);
17501720
}
17511721

17521722
#[track_caller]
@@ -1764,17 +1734,29 @@ fn debug_assert_type_indices_are_ids(ty: ValType) {
17641734
}
17651735
}
17661736

1737+
macro_rules! delegate_to_simd {
1738+
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1739+
$(
1740+
#[cfg(feature = "simd")]
1741+
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Result<()> {
1742+
simd::SimdOperatorValidatorTemp(self).$visit($( $($arg),* )?)
1743+
}
1744+
1745+
#[cfg(not(feature = "simd"))]
1746+
#[allow(unused_variables)]
1747+
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Result<()> {
1748+
self.simd_unavailable()
1749+
}
1750+
)*
1751+
};
1752+
}
1753+
17671754
impl<'a, T> VisitOperator<'a> for OperatorValidatorTemp<'_, '_, T>
17681755
where
17691756
T: WasmModuleResources,
17701757
{
17711758
type Output = Result<()>;
17721759

1773-
#[cfg(feature = "simd")]
1774-
fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> {
1775-
Some(self)
1776-
}
1777-
17781760
fn visit_nop(&mut self) -> Self::Output {
17791761
Ok(())
17801762
}
@@ -4197,6 +4179,8 @@ where
41974179
fn visit_i64_mul_wide_u(&mut self) -> Result<()> {
41984180
self.check_i64_mul_wide()
41994181
}
4182+
4183+
crate::for_each_visit_simd_operator!(delegate_to_simd);
42004184
}
42014185

42024186
#[derive(Clone, Debug)]

0 commit comments

Comments
 (0)