Skip to content

compiler: Clean up weird rustc_abi reexports #136565

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

Merged
merged 2 commits into from
Feb 7, 2025
Merged
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
77 changes: 7 additions & 70 deletions compiler/rustc_abi/src/callconv.rs
Original file line number Diff line number Diff line change
@@ -1,73 +1,10 @@
mod abi {
pub(crate) use crate::Primitive::*;
pub(crate) use crate::Variants;
}

#[cfg(feature = "nightly")]
use rustc_macros::HashStable_Generic;

use crate::{Align, HasDataLayout, Size};
#[cfg(feature = "nightly")]
use crate::{BackendRepr, FieldsShape, TyAbiInterface, TyAndLayout};
use crate::{Primitive, Size, Variants};

#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum RegKind {
Integer,
Float,
Vector,
}

#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Reg {
pub kind: RegKind,
pub size: Size,
}

macro_rules! reg_ctor {
($name:ident, $kind:ident, $bits:expr) => {
pub fn $name() -> Reg {
Reg { kind: RegKind::$kind, size: Size::from_bits($bits) }
}
};
}

impl Reg {
reg_ctor!(i8, Integer, 8);
reg_ctor!(i16, Integer, 16);
reg_ctor!(i32, Integer, 32);
reg_ctor!(i64, Integer, 64);
reg_ctor!(i128, Integer, 128);

reg_ctor!(f32, Float, 32);
reg_ctor!(f64, Float, 64);
}
mod reg;

impl Reg {
pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
let dl = cx.data_layout();
match self.kind {
RegKind::Integer => match self.size.bits() {
1 => dl.i1_align.abi,
2..=8 => dl.i8_align.abi,
9..=16 => dl.i16_align.abi,
17..=32 => dl.i32_align.abi,
33..=64 => dl.i64_align.abi,
65..=128 => dl.i128_align.abi,
_ => panic!("unsupported integer: {self:?}"),
},
RegKind::Float => match self.size.bits() {
16 => dl.f16_align.abi,
32 => dl.f32_align.abi,
64 => dl.f64_align.abi,
128 => dl.f128_align.abi,
_ => panic!("unsupported float: {self:?}"),
},
RegKind::Vector => dl.vector_align(self.size).abi,
}
}
}
pub use reg::{Reg, RegKind};

/// Return value from the `homogeneous_aggregate` test function.
#[derive(Copy, Clone, Debug)]
@@ -134,8 +71,8 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
// The primitive for this algorithm.
BackendRepr::Scalar(scalar) => {
let kind = match scalar.primitive() {
abi::Int(..) | abi::Pointer(_) => RegKind::Integer,
abi::Float(_) => RegKind::Float,
Primitive::Int(..) | Primitive::Pointer(_) => RegKind::Integer,
Primitive::Float(_) => RegKind::Float,
};
Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))
}
@@ -206,8 +143,8 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
let (mut result, mut total) = from_fields_at(*self, Size::ZERO)?;

match &self.variants {
abi::Variants::Single { .. } | abi::Variants::Empty => {}
abi::Variants::Multiple { variants, .. } => {
Variants::Single { .. } | Variants::Empty => {}
Variants::Multiple { variants, .. } => {
// Treat enum variants like union members.
// HACK(eddyb) pretend the `enum` field (discriminant)
// is at the start of every variant (otherwise the gap
63 changes: 63 additions & 0 deletions compiler/rustc_abi/src/callconv/reg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#[cfg(feature = "nightly")]
use rustc_macros::HashStable_Generic;

use crate::{Align, HasDataLayout, Size};

#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum RegKind {
Integer,
Float,
Vector,
}

#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Reg {
pub kind: RegKind,
pub size: Size,
}

macro_rules! reg_ctor {
($name:ident, $kind:ident, $bits:expr) => {
pub fn $name() -> Reg {
Reg { kind: RegKind::$kind, size: Size::from_bits($bits) }
}
};
}

impl Reg {
reg_ctor!(i8, Integer, 8);
reg_ctor!(i16, Integer, 16);
reg_ctor!(i32, Integer, 32);
reg_ctor!(i64, Integer, 64);
reg_ctor!(i128, Integer, 128);

reg_ctor!(f32, Float, 32);
reg_ctor!(f64, Float, 64);
}

impl Reg {
pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
let dl = cx.data_layout();
match self.kind {
RegKind::Integer => match self.size.bits() {
1 => dl.i1_align.abi,
2..=8 => dl.i8_align.abi,
9..=16 => dl.i16_align.abi,
17..=32 => dl.i32_align.abi,
33..=64 => dl.i64_align.abi,
65..=128 => dl.i128_align.abi,
_ => panic!("unsupported integer: {self:?}"),
},
RegKind::Float => match self.size.bits() {
16 => dl.f16_align.abi,
32 => dl.f32_align.abi,
64 => dl.f64_align.abi,
128 => dl.f128_align.abi,
_ => panic!("unsupported float: {self:?}"),
},
RegKind::Vector => dl.vector_align(self.size).abi,
}
}
}
File renamed without changes.
12 changes: 8 additions & 4 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::fmt;
use std::ops::Deref;

use Float::*;
use Primitive::*;
use rustc_data_structures::intern::Interned;
use rustc_macros::HashStable_Generic;

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

// Explicitly import `Float` to avoid ambiguity with `Primitive::Float`.
use crate::{Float, *};

rustc_index::newtype_index! {
/// The *source-order* index of a field in a variant.
@@ -197,7 +199,9 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
C: HasDataLayout,
{
match self.backend_repr {
BackendRepr::Scalar(scalar) => matches!(scalar.primitive(), Float(F32 | F64)),
BackendRepr::Scalar(scalar) => {
matches!(scalar.primitive(), Primitive::Float(Float::F32 | Float::F64))
}
BackendRepr::Memory { .. } => {
if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
self.field(cx, 0).is_single_fp_element(cx)
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/asm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::fmt;
use std::str::FromStr;

use rustc_abi::Size;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::Symbol;

use crate::abi::Size;
use crate::spec::{RelocModel, Target};

pub struct ModifierInfo {
3 changes: 1 addition & 2 deletions compiler/rustc_target/src/callconv/aarch64.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use std::iter;

use rustc_abi::{BackendRepr, Primitive};
use rustc_abi::{BackendRepr, HasDataLayout, Primitive, TyAbiInterface};

use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
use crate::abi::{HasDataLayout, TyAbiInterface};
use crate::spec::{HasTargetSpec, Target};

/// Indicates the variant of the AArch64 ABI we are compiling for.
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/callconv/amdgpu.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::{HasDataLayout, TyAbiInterface};

use crate::abi::call::{ArgAbi, FnAbi};
use crate::abi::{HasDataLayout, TyAbiInterface};

fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>)
where
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/callconv/arm.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::{HasDataLayout, TyAbiInterface};

use crate::abi::call::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform};
use crate::abi::{HasDataLayout, TyAbiInterface};
use crate::spec::HasTargetSpec;

fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
23 changes: 12 additions & 11 deletions compiler/rustc_target/src/callconv/loongarch.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
use crate::abi::{
self, BackendRepr, FieldsShape, HasDataLayout, Size, TyAbiInterface, TyAndLayout,
use rustc_abi::{
BackendRepr, ExternAbi, FieldsShape, HasDataLayout, Primitive, Reg, RegKind, Size,
TyAbiInterface, TyAndLayout, Variants,
};

use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform};
use crate::spec::HasTargetSpec;
use crate::spec::abi::Abi as SpecAbi;

#[derive(Copy, Clone)]
enum RegPassKind {
@@ -42,7 +43,7 @@ where
{
match arg_layout.backend_repr {
BackendRepr::Scalar(scalar) => match scalar.primitive() {
abi::Int(..) | abi::Pointer(_) => {
Primitive::Int(..) | Primitive::Pointer(_) => {
if arg_layout.size.bits() > xlen {
return Err(CannotUseFpConv);
}
@@ -62,7 +63,7 @@ where
_ => return Err(CannotUseFpConv),
}
}
abi::Float(_) => {
Primitive::Float(_) => {
if arg_layout.size.bits() > flen {
return Err(CannotUseFpConv);
}
@@ -115,8 +116,8 @@ where
}
FieldsShape::Arbitrary { .. } => {
match arg_layout.variants {
abi::Variants::Multiple { .. } => return Err(CannotUseFpConv),
abi::Variants::Single { .. } | abi::Variants::Empty => (),
Variants::Multiple { .. } => return Err(CannotUseFpConv),
Variants::Single { .. } | Variants::Empty => (),
}
for i in arg_layout.fields.index_by_increasing_offset() {
let field = arg_layout.field(cx, i);
@@ -314,7 +315,7 @@ fn classify_arg<'a, Ty, C>(

fn extend_integer_width<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
if let abi::Int(i, _) = scalar.primitive() {
if let Primitive::Int(i, _) = scalar.primitive() {
// 32-bit integers are always sign-extended
if i.size().bits() == 32 && xlen > 32 {
if let PassMode::Direct(ref mut attrs) = arg.mode {
@@ -363,12 +364,12 @@ where
}
}

pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, abi: SpecAbi)
pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, abi: ExternAbi)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
if abi == SpecAbi::RustIntrinsic {
if abi == ExternAbi::RustIntrinsic {
return;
}

3 changes: 2 additions & 1 deletion compiler/rustc_target/src/callconv/mips.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::{HasDataLayout, Size};

use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
use crate::abi::{HasDataLayout, Size};

fn classify_ret<Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
where
33 changes: 18 additions & 15 deletions compiler/rustc_target/src/callconv/mips64.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::abi::call::{
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, PassMode, Reg, Uniform,
use rustc_abi::{
BackendRepr, FieldsShape, Float, HasDataLayout, Primitive, Reg, Size, TyAbiInterface,
};

use crate::callconv::{
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, PassMode, Uniform,
};
use crate::abi::{self, HasDataLayout, Size, TyAbiInterface};

fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
// Always sign extend u32 values on 64-bit mips
if let abi::BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
if let abi::Int(i, signed) = scalar.primitive() {
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
if let Primitive::Int(i, signed) = scalar.primitive() {
if !signed && i.size().bits() == 32 {
if let PassMode::Direct(ref mut attrs) = arg.mode {
attrs.ext(ArgExtension::Sext);
@@ -25,9 +28,9 @@ where
C: HasDataLayout,
{
match ret.layout.field(cx, i).backend_repr {
abi::BackendRepr::Scalar(scalar) => match scalar.primitive() {
abi::Float(abi::F32) => Some(Reg::f32()),
abi::Float(abi::F64) => Some(Reg::f64()),
BackendRepr::Scalar(scalar) => match scalar.primitive() {
Primitive::Float(Float::F32) => Some(Reg::f32()),
Primitive::Float(Float::F64) => Some(Reg::f64()),
_ => None,
},
_ => None,
@@ -51,7 +54,7 @@ where
// use of float registers to structures (not unions) containing exactly one or two
// float fields.

if let abi::FieldsShape::Arbitrary { .. } = ret.layout.fields {
if let FieldsShape::Arbitrary { .. } = ret.layout.fields {
if ret.layout.fields.count() == 1 {
if let Some(reg) = float_reg(cx, ret, 0) {
ret.cast_to(reg);
@@ -90,16 +93,16 @@ where
let mut prefix_index = 0;

match arg.layout.fields {
abi::FieldsShape::Primitive => unreachable!(),
abi::FieldsShape::Array { .. } => {
FieldsShape::Primitive => unreachable!(),
FieldsShape::Array { .. } => {
// Arrays are passed indirectly
arg.make_indirect();
return;
}
abi::FieldsShape::Union(_) => {
FieldsShape::Union(_) => {
// Unions and are always treated as a series of 64-bit integer chunks
}
abi::FieldsShape::Arbitrary { .. } => {
FieldsShape::Arbitrary { .. } => {
// Structures are split up into a series of 64-bit integer chunks, but any aligned
// doubles not part of another aggregate are passed as floats.
let mut last_offset = Size::ZERO;
@@ -109,8 +112,8 @@ where
let offset = arg.layout.fields.offset(i);

// We only care about aligned doubles
if let abi::BackendRepr::Scalar(scalar) = field.backend_repr {
if scalar.primitive() == abi::Float(abi::F64) {
if let BackendRepr::Scalar(scalar) = field.backend_repr {
if scalar.primitive() == Primitive::Float(Float::F64) {
if offset.is_aligned(dl.f64_align.abi) {
// Insert enough integers to cover [last_offset, offset)
assert!(last_offset.is_aligned(dl.f64_align.abi));
Loading