compiler: BackendRepr::inherent_{size,align} -> scalar_{size,align}

This pair of fn was introduced to perform invariant checks for scalars.
Their current behavior doesn't mesh as well with checking SIMD types,
so change the name of the fn to reflect their actual use-case and
refactor the corresponding checks.

Also simplify the returns from Option<AbiAndPrefAlign> to Option<Align>,
because every site was mapping away the "preferred" alignment anyways.
This commit is contained in:
Jubilee Young
2025-02-18 18:53:15 -08:00
parent efff15afea
commit 5c474fd99b
3 changed files with 78 additions and 63 deletions

View File

@@ -1454,37 +1454,38 @@ impl BackendRepr {
matches!(*self, BackendRepr::Scalar(s) if s.is_bool())
}
/// Returns the fixed alignment of this ABI, if any is mandated.
pub fn inherent_align<C: HasDataLayout>(&self, cx: &C) -> Option<AbiAndPrefAlign> {
Some(match *self {
BackendRepr::Scalar(s) => s.align(cx),
BackendRepr::ScalarPair(s1, s2) => s1.align(cx).max(s2.align(cx)),
BackendRepr::Vector { element, count } => {
cx.data_layout().vector_align(element.size(cx) * count)
}
BackendRepr::Memory { .. } => return None,
})
/// The psABI alignment for a `Scalar` or `ScalarPair`
///
/// `None` for other variants.
pub fn scalar_align<C: HasDataLayout>(&self, cx: &C) -> Option<Align> {
match *self {
BackendRepr::Scalar(s) => Some(s.align(cx).abi),
BackendRepr::ScalarPair(s1, s2) => Some(s1.align(cx).max(s2.align(cx)).abi),
// The align of a Vector can vary in surprising ways
BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => None,
}
}
/// Returns the fixed size of this ABI, if any is mandated.
pub fn inherent_size<C: HasDataLayout>(&self, cx: &C) -> Option<Size> {
Some(match *self {
BackendRepr::Scalar(s) => {
// No padding in scalars.
s.size(cx)
}
/// The psABI size for a `Scalar` or `ScalarPair`
///
/// `None` for other variants
pub fn scalar_size<C: HasDataLayout>(&self, cx: &C) -> Option<Size> {
match *self {
// No padding in scalars.
BackendRepr::Scalar(s) => Some(s.size(cx)),
// May have some padding between the pair.
BackendRepr::ScalarPair(s1, s2) => {
// May have some padding between the pair.
let field2_offset = s1.size(cx).align_to(s2.align(cx).abi);
(field2_offset + s2.size(cx)).align_to(self.inherent_align(cx)?.abi)
let size = (field2_offset + s2.size(cx)).align_to(
self.scalar_align(cx)
// We absolutely must have an answer here or everything is FUBAR.
.unwrap(),
);
Some(size)
}
BackendRepr::Vector { element, count } => {
// No padding in vectors, except possibly for trailing padding
// to make the size a multiple of align (e.g. for vectors of size 3).
(element.size(cx) * count).align_to(self.inherent_align(cx)?.abi)
}
BackendRepr::Memory { .. } => return None,
})
// The size of a Vector can vary in surprising ways
BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => None,
}
}
/// Discard validity range information and allow undef.