Skip to content
Open
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
58 changes: 58 additions & 0 deletions library/core/src/attribute_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,3 +581,61 @@ mod proc_macro_attribute {}
///
/// [the `link_section` attribute]: ../reference/abi.html#the-link_section-attribute
mod link_section_attribute {}

#[doc(attribute = "target_feature")]
//
/// Enables extra CPU instructions for a single function.
///
/// A program is compiled for a baseline CPU, so instructions that only newer CPUs support go

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Where does the baseline come from?

/// unused even when the machine running the program has them. `#[target_feature(enable = "...")]`
/// compiles one function with extra features turned on while the rest of the crate keeps the
/// baseline. The `-C target-feature` and `-C target-cpu` compiler flags enable features for the
/// whole crate instead, which raises the minimum CPU the binary runs on.
Comment on lines +592 to +593

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is an oddly dangling remark without flow.

It seems better to first mention the -C flags, and then pivot from there to the per-function version. Also, -Ctarget-cpu is very different from -Ctarget-fature, so throwing them into one bag here is quite confusing. -Ctarget-feature and #[target_feature] are closely related, they work on the same set of features; that should be mentioned.

///
/// The usual shape is to ask the CPU what it supports at run time, dispatch into the specialized
/// function, and keep a fallback for everything else:
///
/// ```
/// # #[cfg(target_arch = "x86_64")] {
/// #[target_feature(enable = "avx2")]
/// fn sum_avx2(xs: &[u32]) -> u32 {
/// // The compiler may use AVX2 instructions in here.
/// xs.iter().sum()
/// }
///
/// fn sum(xs: &[u32]) -> u32 {
/// if is_x86_feature_detected!("avx2") {
/// // SAFETY: the CPU was just checked for AVX2 support.
/// unsafe { sum_avx2(xs) }
/// } else {
/// xs.iter().sum()
/// }
/// }
///
/// assert_eq!(sum(&[1, 2, 3]), 6);
/// # }
/// ```
///
/// The standard library provides a detection macro for each architecture, such as
/// [`is_x86_feature_detected`] and [`is_aarch64_feature_detected`].
///
/// Calling a `#[target_feature]` function on a CPU without the features is undefined behavior, so
/// the call needs an `unsafe` block. The exception is a caller that enables the same features
/// itself: there the compiler already knows the instructions are available, so the call is safe.
/// Closures written inside such a function inherit its features.
///
/// The attribute does not combine with [`inline(always)`], since inlining the body into a caller
/// that lacks the features would be unsound. The function does not implement the `Fn` traits and
/// only coerces to an `unsafe fn` pointer, so pass a closure that calls it instead.
///
/// The value of `enable` is a comma-separated list of feature names. Names are specific to an
/// architecture, and one that is not valid for the target is an error. Some are still unstable and
/// need a nightly feature gate.
///
/// For more information, see the Reference on [the `target_feature` attribute].
///
/// [`is_x86_feature_detected`]: ../std/arch/macro.is_x86_feature_detected.html
/// [`is_aarch64_feature_detected`]: ../std/arch/macro.is_aarch64_feature_detected.html
/// [`inline(always)`]: ./attribute.inline.html
/// [the `target_feature` attribute]: ../reference/attributes/codegen.html#the-target_feature-attribute
mod target_feature_attribute {}
Loading