Skip to content

Remove rustc's notion of "preferred" alignment AKA __alignof #141803

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
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
20 changes: 7 additions & 13 deletions compiler/rustc_abi/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_index::bit_set::BitMatrix;
use tracing::debug;

use crate::{
AbiAndPrefAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer,
AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer,
LayoutData, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding,
Variants, WrappingRange,
};
Expand Down Expand Up @@ -173,13 +173,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
// Non-power-of-two vectors have padding up to the next power-of-two.
// If we're a packed repr, remove the padding while keeping the alignment as close
// to a vector as possible.
(
BackendRepr::Memory { sized: true },
AbiAndPrefAlign {
abi: Align::max_aligned_factor(size),
pref: dl.llvmlike_vector_align(size).pref,
},
)
(BackendRepr::Memory { sized: true }, AbiAlign { abi: Align::max_aligned_factor(size) })
} else {
(BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size))
};
Expand Down Expand Up @@ -435,13 +429,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
}

if let Some(pack) = repr.pack {
align = align.min(AbiAndPrefAlign::new(pack));
align = align.min(AbiAlign::new(pack));
}
// The unadjusted ABI alignment does not include repr(align), but does include repr(pack).
// See documentation on `LayoutS::unadjusted_abi_align`.
let unadjusted_abi_align = align.abi;
if let Some(repr_align) = repr.align {
align = align.max(AbiAndPrefAlign::new(repr_align));
align = align.max(AbiAlign::new(repr_align));
}
// `align` must not be modified after this, or `unadjusted_abi_align` could be inaccurate.
let align = align;
Expand Down Expand Up @@ -1289,7 +1283,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
let prefix_align =
if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align };
align = align.max(AbiAndPrefAlign::new(prefix_align));
align = align.max(AbiAlign::new(prefix_align));
offset = prefix_size.align_to(prefix_align);
}
for &i in &inverse_memory_index {
Expand All @@ -1308,7 +1302,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {

// Invariant: offset < dl.obj_size_bound() <= 1<<61
let field_align = if let Some(pack) = pack {
field.align.min(AbiAndPrefAlign::new(pack))
field.align.min(AbiAlign::new(pack))
} else {
field.align
};
Expand Down Expand Up @@ -1342,7 +1336,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
// See documentation on `LayoutS::unadjusted_abi_align`.
let unadjusted_abi_align = align.abi;
if let Some(repr_align) = repr.align {
align = align.max(AbiAndPrefAlign::new(repr_align));
align = align.max(AbiAlign::new(repr_align));
}
// `align` must not be modified after this point, or `unadjusted_abi_align` could be inaccurate.
let align = align;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_data_structures::intern::Interned;
use rustc_macros::HashStable_Generic;

use crate::{
AbiAndPrefAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche,
AbiAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche,
PointeeInfo, Primitive, Scalar, Size, TargetDataLayout, Variants,
};

Expand Down Expand Up @@ -93,7 +93,7 @@ impl<'a> Layout<'a> {
self.0.0.largest_niche
}

pub fn align(self) -> AbiAndPrefAlign {
pub fn align(self) -> AbiAlign {
self.0.0.align
}

Expand Down
100 changes: 53 additions & 47 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use std::fmt;
#[cfg(feature = "nightly")]
use std::iter::Step;
use std::num::{NonZeroUsize, ParseIntError};
use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub};
use std::ops::{Add, AddAssign, Deref, Mul, RangeInclusive, Sub};
use std::str::FromStr;

use bitflags::bitflags;
Expand Down Expand Up @@ -226,22 +226,22 @@ pub const MAX_SIMD_LANES: u64 = 1 << 0xF;
#[derive(Debug, PartialEq, Eq)]
pub struct TargetDataLayout {
pub endian: Endian,
pub i1_align: AbiAndPrefAlign,
pub i8_align: AbiAndPrefAlign,
pub i16_align: AbiAndPrefAlign,
pub i32_align: AbiAndPrefAlign,
pub i64_align: AbiAndPrefAlign,
pub i128_align: AbiAndPrefAlign,
pub f16_align: AbiAndPrefAlign,
pub f32_align: AbiAndPrefAlign,
pub f64_align: AbiAndPrefAlign,
pub f128_align: AbiAndPrefAlign,
pub i1_align: AbiAlign,
pub i8_align: AbiAlign,
pub i16_align: AbiAlign,
pub i32_align: AbiAlign,
pub i64_align: AbiAlign,
pub i128_align: AbiAlign,
pub f16_align: AbiAlign,
pub f32_align: AbiAlign,
pub f64_align: AbiAlign,
pub f128_align: AbiAlign,
pub pointer_size: Size,
pub pointer_align: AbiAndPrefAlign,
pub aggregate_align: AbiAndPrefAlign,
pub pointer_align: AbiAlign,
pub aggregate_align: AbiAlign,

/// Alignments for vector types.
pub vector_align: Vec<(Size, AbiAndPrefAlign)>,
pub vector_align: Vec<(Size, AbiAlign)>,

pub instruction_address_space: AddressSpace,

Expand All @@ -257,22 +257,22 @@ impl Default for TargetDataLayout {
let align = |bits| Align::from_bits(bits).unwrap();
TargetDataLayout {
endian: Endian::Big,
i1_align: AbiAndPrefAlign::new(align(8)),
i8_align: AbiAndPrefAlign::new(align(8)),
i16_align: AbiAndPrefAlign::new(align(16)),
i32_align: AbiAndPrefAlign::new(align(32)),
i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
f16_align: AbiAndPrefAlign::new(align(16)),
f32_align: AbiAndPrefAlign::new(align(32)),
f64_align: AbiAndPrefAlign::new(align(64)),
f128_align: AbiAndPrefAlign::new(align(128)),
i1_align: AbiAlign::new(align(8)),
i8_align: AbiAlign::new(align(8)),
i16_align: AbiAlign::new(align(16)),
i32_align: AbiAlign::new(align(32)),
i64_align: AbiAlign::new(align(32)),
i128_align: AbiAlign::new(align(32)),
f16_align: AbiAlign::new(align(16)),
f32_align: AbiAlign::new(align(32)),
f64_align: AbiAlign::new(align(64)),
f128_align: AbiAlign::new(align(128)),
pointer_size: Size::from_bits(64),
pointer_align: AbiAndPrefAlign::new(align(64)),
aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) },
pointer_align: AbiAlign::new(align(64)),
aggregate_align: AbiAlign { abi: align(8) },
vector_align: vec![
(Size::from_bits(64), AbiAndPrefAlign::new(align(64))),
(Size::from_bits(128), AbiAndPrefAlign::new(align(128))),
(Size::from_bits(64), AbiAlign::new(align(64))),
(Size::from_bits(128), AbiAlign::new(align(128))),
],
instruction_address_space: AddressSpace::DATA,
c_enum_min_size: Integer::I32,
Expand Down Expand Up @@ -330,8 +330,7 @@ impl TargetDataLayout {
.map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err })
};
let abi = parse_bits(s[0], "alignment", cause)?;
let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?;
Ok(AbiAndPrefAlign { abi: align_from_bits(abi)?, pref: align_from_bits(pref)? })
Ok(AbiAlign::new(align_from_bits(abi)?))
};

let mut dl = TargetDataLayout::default();
Expand Down Expand Up @@ -426,7 +425,7 @@ impl TargetDataLayout {

/// psABI-mandated alignment for a vector type, if any
#[inline]
fn cabi_vector_align(&self, vec_size: Size) -> Option<AbiAndPrefAlign> {
fn cabi_vector_align(&self, vec_size: Size) -> Option<AbiAlign> {
self.vector_align
.iter()
.find(|(size, _align)| *size == vec_size)
Expand All @@ -435,8 +434,8 @@ impl TargetDataLayout {

/// an alignment resembling the one LLVM would pick for a vector
#[inline]
pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAndPrefAlign {
self.cabi_vector_align(vec_size).unwrap_or(AbiAndPrefAlign::new(
pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAlign {
self.cabi_vector_align(vec_size).unwrap_or(AbiAlign::new(
Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(),
))
}
Expand Down Expand Up @@ -864,25 +863,32 @@ impl Align {
/// It is of effectively no consequence for layout in structs and on the stack.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
pub struct AbiAndPrefAlign {
pub struct AbiAlign {
pub abi: Align,
pub pref: Align,
}

impl AbiAndPrefAlign {
impl AbiAlign {
#[inline]
pub fn new(align: Align) -> AbiAndPrefAlign {
AbiAndPrefAlign { abi: align, pref: align }
pub fn new(align: Align) -> AbiAlign {
AbiAlign { abi: align }
}

#[inline]
pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign {
AbiAndPrefAlign { abi: self.abi.min(other.abi), pref: self.pref.min(other.pref) }
pub fn min(self, other: AbiAlign) -> AbiAlign {
AbiAlign { abi: self.abi.min(other.abi) }
}

#[inline]
pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign {
AbiAndPrefAlign { abi: self.abi.max(other.abi), pref: self.pref.max(other.pref) }
pub fn max(self, other: AbiAlign) -> AbiAlign {
AbiAlign { abi: self.abi.max(other.abi) }
}
}

impl Deref for AbiAlign {
type Target = Align;

fn deref(&self) -> &Self::Target {
&self.abi
}
}

Expand Down Expand Up @@ -945,7 +951,7 @@ impl Integer {
}
}

pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
use Integer::*;
let dl = cx.data_layout();

Expand Down Expand Up @@ -1058,7 +1064,7 @@ impl Float {
}
}

pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
use Float::*;
let dl = cx.data_layout();

Expand Down Expand Up @@ -1102,7 +1108,7 @@ impl Primitive {
}
}

pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAlign {
use Primitive::*;
let dl = cx.data_layout();

Expand Down Expand Up @@ -1225,7 +1231,7 @@ impl Scalar {
}
}

pub fn align(self, cx: &impl HasDataLayout) -> AbiAndPrefAlign {
pub fn align(self, cx: &impl HasDataLayout) -> AbiAlign {
self.primitive().align(cx)
}

Expand Down Expand Up @@ -1731,7 +1737,7 @@ pub struct LayoutData<FieldIdx: Idx, VariantIdx: Idx> {
/// especially in the case of by-pointer struct returns, which allocate stack even when unused.
pub uninhabited: bool,

pub align: AbiAndPrefAlign,
pub align: AbiAlign,
pub size: Size,

/// The largest alignment explicitly requested with `repr(align)` on this type or any field.
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,11 +812,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
dest.write_cvalue(fx, val);
}

sym::pref_align_of
| sym::needs_drop
| sym::type_id
| sym::type_name
| sym::variant_count => {
sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
intrinsic_args!(fx, args => (); intrinsic);

let const_val = fx
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
value
}
sym::pref_align_of
| sym::needs_drop
| sym::type_id
| sym::type_name
| sym::variant_count => {
sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
let value = bx.tcx().const_eval_instance(bx.typing_env(), instance, span).unwrap();
OperandRef::from_const(bx, value, result.layout.ty).immediate_or_packed_pair(bx)
}
Expand Down
15 changes: 2 additions & 13 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,6 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
ensure_monomorphic_enough(tcx, tp_ty)?;
ConstValue::from_bool(tp_ty.needs_drop(tcx, typing_env))
}
sym::pref_align_of => {
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
let layout = tcx
.layout_of(typing_env.as_query_input(tp_ty))
.map_err(|e| err_inval!(Layout(*e)))?;
ConstValue::from_target_usize(layout.align.pref.bytes(), &tcx)
}
sym::type_id => {
ensure_monomorphic_enough(tcx, tp_ty)?;
ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128())
Expand Down Expand Up @@ -144,14 +137,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_scalar(Scalar::from_target_usize(result, self), dest)?;
}

sym::pref_align_of
| sym::needs_drop
| sym::type_id
| sym::type_name
| sym::variant_count => {
sym::needs_drop | sym::type_id | sym::type_name | sym::variant_count => {
let gid = GlobalId { instance, promoted: None };
let ty = match intrinsic_name {
sym::pref_align_of | sym::variant_count => self.tcx.types.usize,
sym::variant_count => self.tcx.types.usize,
sym::needs_drop => self.tcx.types.bool,
sym::type_id => self.tcx.types.u128,
sym::type_name => Ty::new_static_str(self.tcx.tcx),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/removed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ declare_features! (
/// Allows exhaustive integer pattern matching with `usize::MAX`/`isize::MIN`/`isize::MAX`.
(removed, precise_pointer_size_matching, "1.32.0", Some(56354),
Some("removed in favor of half-open ranges")),
(removed, pref_align_of, "CURRENT_RUSTC_VERSION", Some(91971),
Some("removed due to marginal use and inducing compiler complications")),
(removed, proc_macro_expr, "1.27.0", Some(54727),
Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
(removed, proc_macro_gen, "1.27.0", Some(54727),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ pub(crate) fn check_intrinsic_type(
sym::abort => (0, 0, vec![], tcx.types.never),
sym::unreachable => (0, 0, vec![], tcx.types.never),
sym::breakpoint => (0, 0, vec![], tcx.types.unit),
sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => {
sym::size_of | sym::min_align_of | sym::variant_count => {
(1, 0, vec![], tcx.types.usize)
}
sym::size_of_val | sym::min_align_of_val => {
Expand Down
9 changes: 0 additions & 9 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3485,15 +3485,6 @@ pub const fn size_of<T>() -> usize;
#[rustc_intrinsic]
pub const fn min_align_of<T>() -> usize;
Copy link
Member

Choose a reason for hiding this comment

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

Also in the future, we should then rename this to just align_of.


/// The preferred alignment of a type.
///
/// This intrinsic does not have a stable counterpart.
/// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971).
#[rustc_nounwind]
#[unstable(feature = "core_intrinsics", issue = "none")]
#[rustc_intrinsic]
pub const unsafe fn pref_align_of<T>() -> usize;

/// Returns the number of variants of the type `T` cast to a `usize`;
/// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
///
Expand Down
6 changes: 2 additions & 4 deletions tests/ui/abi/c-zst.aarch64-darwin.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
ty: (),
layout: Layout {
size: Size(0 bytes),
align: AbiAndPrefAlign {
align: AbiAlign {
abi: $SOME_ALIGN,
pref: $SOME_ALIGN,
},
backend_repr: Memory {
sized: true,
Expand All @@ -34,9 +33,8 @@ error: fn_abi_of(pass_zst) = FnAbi {
ty: (),
layout: Layout {
size: Size(0 bytes),
align: AbiAndPrefAlign {
align: AbiAlign {
abi: $SOME_ALIGN,
pref: $SOME_ALIGN,
},
backend_repr: Memory {
sized: true,
Expand Down
Loading
Loading