Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Detect and optimize SIMD-like struct #146049

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

Open
so-lovely wants to merge 1 commit into rust-lang:master
base: master
Choose a base branch
Loading
from so-lovely:master
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
64 changes: 64 additions & 0 deletions compiler/rustc_ty_utils/src/layout.rs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,55 @@ fn layout_of_uncached<'tcx>(

// ADTs.
ty::Adt(def, args) => {
// SIMD-like struct detection and optimization with conservative safety constraints
// Check if this is a user-defined struct like Vector<T, const N: usize>([T; N])
// that should be treated as SIMD-friendly even without #[repr(simd)]
if def.is_struct()
&& def.variants().len() == 1
&& def.variant(FIRST_VARIANT).fields.len() == 1
&& def.did().is_local() // Only user crate types
{
// Safety: exclude system crates by checking crate name
let crate_name = tcx.crate_name(def.did().krate);
let crate_name_str = crate_name.as_str();

// Exclude known system/compiler crates
if !matches!(crate_name_str,
"core" | "std" | "alloc" | "proc_macro" | "test" |
"rustc_std_workspace_core" | "rustc_std_workspace_alloc" |
"compiler_builtins" | "libc" | "unwind" | "panic_abort" |
"panic_unwind" | "adler2" | "object" | "memchr"
) {
Comment on lines +582 to +587
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do these get special treatment?

Name matching specific ecosystem crates to give them special treatment is very hazardous. Occasionally we need to match std crates, for which we have the list at

pub const STDLIB_STABLE_CRATES: &[Symbol] = &[sym::std, sym::core, sym::alloc, sym::proc_macro];
, but I can't think of a reason it would be needed here.

fmease and jieyouxu reacted with thumbs up emoji
let field_ty = def.variant(FIRST_VARIANT).fields[FieldIdx::ZERO].ty(tcx, args);

// Check if the single field is an array of SIMD-friendly types
if let ty::Array(element_ty, array_len) = field_ty.kind() {
if is_simd_friendly_element_type(*element_ty) {
if let Some(len) = extract_const_value(cx, ty, *array_len)?
.try_to_target_usize(tcx)
{
// Common SIMD sizes: 4, 8, 16 (conservative range)
if matches!(len, 4 | 8 | 16) {
Comment on lines +591 to +597
Copy link
Contributor

Choose a reason for hiding this comment

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

Use a let chain to flatten this nesting.

// REQUIRE explicit alignment hint - this is the key safety measure
let has_simd_alignment = def.repr().align
.map_or(false, |align| {
let align_bytes = align.bytes();
// Must have 16+ byte alignment to suggest SIMD intent
align_bytes >= 16 && align_bytes.is_power_of_two()
});

// Only apply if user explicitly requested SIMD-like alignment
if has_simd_alignment {
let e_ly = cx.layout_of(*element_ty)?;
return Ok(map_layout(cx.calc.simd_type(e_ly, len, false))?);
}
}
}
}
}
}
}

// Cache the field layouts.
let variants = def
.variants()
Expand Down Expand Up @@ -706,6 +755,21 @@ fn layout_of_uncached<'tcx>(
})
}

/// Check if a type is suitable for SIMD operations
fn is_simd_friendly_element_type<'tcx>(ty: Ty<'tcx>) -> bool {
match ty.kind() {
// Floating-point types - most common SIMD use case
ty::Float(_) => true,
// Integer types - common for SIMD
ty::Int(_) | ty::Uint(_) => true,
// Bool can be vectorized in some contexts
ty::Bool => true,
// Pointers removed to avoid affecting system types like TypeId
// Other types are not typically vectorizable
_ => false,
}
}

fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx>, layout: TyAndLayout<'tcx>) {
// Ignore layouts that are done with non-empty environments or
// non-monomorphic layouts, as the user only wants to see the stuff
Expand Down
Loading

AltStyle によって変換されたページ (->オリジナル) /