Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/control/group/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ use core::{mem, ptr};
// a 32-bit architecture will just end up being more expensive because
// shifts and multiplies will need to be emulated.

cfg_if! {
if #[cfg(any(
cfg_select! {
any(
target_pointer_width = "64",
target_arch = "aarch64",
target_arch = "x86_64",
target_arch = "wasm32",
))] {
) => {
type GroupWord = u64;
type NonZeroGroupWord = core::num::NonZeroU64;
} else {
}
_ => {
type GroupWord = u32;
type NonZeroGroupWord = core::num::NonZeroU32;
}
Expand Down
20 changes: 12 additions & 8 deletions src/control/group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// modules. Be sure to edit `ci/tools.sh` to add in the necessary cfgs if you
// change these, so that your implementation gets properly linted.

cfg_if! {
cfg_select! {
// Use the SSE2 implementation if possible: it allows us to scan 16 buckets
// at once instead of 8. We don't bother with AVX since it would require
// runtime dispatch and wouldn't gain us much anyways: the probability of
Expand All @@ -14,32 +14,36 @@ cfg_if! {
// I attempted an implementation on ARM using NEON instructions, but it
// turns out that most NEON instructions have multi-cycle latency, which in
// the end outweighs any gains over the generic implementation.
if #[cfg(all(
all(
target_feature = "sse2",
any(target_arch = "x86", target_arch = "x86_64"),
not(miri),
))] {
) => {
mod sse2;
use sse2 as imp;
} else if #[cfg(all(
}
all(
target_arch = "aarch64",
target_feature = "neon",
// NEON intrinsics are currently broken on big-endian targets.
// See https://github.com/rust-lang/stdarch/issues/1484.
target_endian = "little",
not(miri),
))] {
) => {
mod neon;
use neon as imp;
} else if #[cfg(all(
}
all(
feature = "nightly",
target_arch = "loongarch64",
target_feature = "lsx",
not(miri),
))] {
) => {
mod lsx;
use lsx as imp;
} else {
}

_ => {
mod generic;
use generic as imp;
}
Expand Down
78 changes: 25 additions & 53 deletions src/macros.rs
Comment thread
clarfonthey marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,70 +1,42 @@
// See the cfg-if crate.
#[expect(unused_macro_rules)]
macro_rules! cfg_if {
// match if/else chains with a final `else`
($(
if #[cfg($($meta:meta),*)] { $($it:item)* }
) else * else {
$($it2:item)*
}) => {
cfg_if! {
@__items
() ;
$( ( ($($meta),*) ($($it)*) ), )*
( () ($($it2)*) ),
}
// FIXME: remove once we bump MSRV >= 1.95.0
// Originally by @folkertdev on Zulip:
// https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/compiler-builtins.20msrv.20policy.3F/near/606320965
/// Fallback `cfg_select!` on older Rust.
///
/// Requires braces around output, but works for items and expressions.
#[cfg(not(feature = "nightly"))]
#[macro_export]
macro_rules! cfg_select {
({ $($tt:tt)* }) => {{
$crate::cfg_select! { $($tt)* }
}};
(_ => { $($output:tt)* }) => {
$($output)*
};

// match if/else chains lacking a final `else`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We actually never used this branch, but I guess we wanted it for completeness.

(
if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
$(
else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
)*
$cfg:meta => $output:tt
$($( $rest:tt )+)?
) => {
cfg_if! {
@__items
() ;
( ($($i_met),*) ($($i_it)*) ),
$( ( ($($e_met),*) ($($e_it)*) ), )*
( () () ),
}
};

// Internal and recursive macro to emit all the items
//
// Collects all the negated cfgs in a list at the beginning and after the
// semicolon is all the remaining items
(@__items ($($not:meta,)*) ; ) => {};
(@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
// Emit all items within one block, applying an appropriate #[cfg]. The
// #[cfg] will require all `$m` matchers specified and must also negate
// all previous matchers.
cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }

// Recurse to emit all other items in `$rest`, and when we do so add all
// our `$m` matchers to the list of `$not` matchers as future emissions
// will have to negate everything we just matched as well.
cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
};

// Internal macro to Apply a cfg attribute to a list of items
(@__apply $m:meta, $($it:item)*) => {
$(#[$m] $it)*
};
#[cfg($cfg)]
$crate::cfg_select! { _ => $output }
$(
#[cfg(not($cfg))]
$crate::cfg_select! { $($rest)+ }
)?
}
}

// Helper macro for specialization. This also helps avoid parse errors if the
// default fn syntax for specialization changes in the future.
#[cfg(feature = "nightly")]
macro_rules! default_fn {
(#[$($a:tt)*] $($tt:tt)*) => {
(#[$($a:tt)*] $($tt:tt)*) => {
#[$($a)*] default $($tt)*
}
}
#[cfg(not(feature = "nightly"))]
macro_rules! default_fn {
($($tt:tt)*) => {
($($tt:tt)*) => {
$($tt)*
}
}
Loading