compiler: Parse p- specs in datalayout string, allow definition of custom default data address space

This commit is contained in:
Edoardo Marangoni
2025-06-29 12:11:51 +02:00
committed by Edoardo Marangoni
parent 733b47ea4b
commit 93f1201c06
58 changed files with 416 additions and 170 deletions

View File

@@ -334,7 +334,7 @@ where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
let xlen = cx.data_layout().pointer_size.bits();
let xlen = cx.data_layout().pointer_size().bits();
let flen = match &cx.target_spec().llvm_abiname[..] {
"ilp32f" | "lp64f" => 32,
"ilp32d" | "lp64d" => 64,
@@ -369,7 +369,7 @@ where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
let grlen = cx.data_layout().pointer_size.bits();
let grlen = cx.data_layout().pointer_size().bits();
for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {

View File

@@ -10,7 +10,7 @@ where
ret.extend_integer_width_to(32);
} else {
ret.make_indirect();
*offset += cx.data_layout().pointer_size;
*offset += cx.data_layout().pointer_size();
}
}

View File

@@ -733,7 +733,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
}
if arg_idx.is_none()
&& arg.layout.size > Primitive::Pointer(AddressSpace::DATA).size(cx) * 2
&& arg.layout.size > Primitive::Pointer(AddressSpace::ZERO).size(cx) * 2
&& !matches!(arg.layout.backend_repr, BackendRepr::SimdVector { .. })
{
// Return values larger than 2 registers using a return area
@@ -792,7 +792,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
let size = arg.layout.size;
if arg.layout.is_sized()
&& size <= Primitive::Pointer(AddressSpace::DATA).size(cx)
&& size <= Primitive::Pointer(AddressSpace::ZERO).size(cx)
{
// We want to pass small aggregates as immediates, but using
// an LLVM aggregate type for this leads to bad optimizations,

View File

@@ -418,7 +418,7 @@ where
"ilp32d" | "lp64d" => 64,
_ => 0,
};
let xlen = cx.data_layout().pointer_size.bits();
let xlen = cx.data_layout().pointer_size().bits();
let mut avail_gprs = 8;
let mut avail_fprs = 8;
@@ -448,7 +448,7 @@ where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
let xlen = cx.data_layout().pointer_size.bits();
let xlen = cx.data_layout().pointer_size().bits();
for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {

View File

@@ -10,7 +10,7 @@ where
ret.extend_integer_width_to(32);
} else {
ret.make_indirect();
*offset += cx.data_layout().pointer_size;
*offset += cx.data_layout().pointer_size();
}
}

View File

@@ -219,7 +219,7 @@ where
// SSE ABI. We prefer this over integer registers as float scalars need to be in SSE
// registers for float operations, so that's the best place to pass them around.
fn_abi.ret.cast_to(Reg { kind: RegKind::Vector, size: fn_abi.ret.layout.size });
} else if fn_abi.ret.layout.size <= Primitive::Pointer(AddressSpace::DATA).size(cx) {
} else if fn_abi.ret.layout.size <= Primitive::Pointer(AddressSpace::ZERO).size(cx) {
// Same size or smaller than pointer, return in an integer register.
fn_abi.ret.cast_to(Reg { kind: RegKind::Integer, size: fn_abi.ret.layout.size });
} else {

View File

@@ -2198,7 +2198,10 @@ pub struct TargetMetadata {
impl Target {
pub fn parse_data_layout(&self) -> Result<TargetDataLayout, TargetDataLayoutErrors<'_>> {
let mut dl = TargetDataLayout::parse_from_llvm_datalayout_string(&self.data_layout)?;
let mut dl = TargetDataLayout::parse_from_llvm_datalayout_string(
&self.data_layout,
self.options.default_address_space,
)?;
// Perform consistency checks against the Target information.
if dl.endian != self.endian {
@@ -2209,9 +2212,10 @@ impl Target {
}
let target_pointer_width: u64 = self.pointer_width.into();
if dl.pointer_size.bits() != target_pointer_width {
let dl_pointer_size: u64 = dl.pointer_size().bits();
if dl_pointer_size != target_pointer_width {
return Err(TargetDataLayoutErrors::InconsistentTargetPointerWidth {
pointer_size: dl.pointer_size.bits(),
pointer_size: dl_pointer_size,
target: self.pointer_width,
});
}
@@ -2650,6 +2654,11 @@ pub struct TargetOptions {
/// Whether the target supports XRay instrumentation.
pub supports_xray: bool,
/// The default address space for this target. When using LLVM as a backend, most targets simply
/// use LLVM's default address space (0). Some other targets, such as CHERI targets, use a
/// custom default address space (in this specific case, `200`).
pub default_address_space: rustc_abi::AddressSpace,
/// Whether the targets supports -Z small-data-threshold
small_data_threshold_support: SmallDataThresholdSupport,
}
@@ -2878,6 +2887,7 @@ impl Default for TargetOptions {
entry_name: "main".into(),
entry_abi: CanonAbi::C,
supports_xray: false,
default_address_space: rustc_abi::AddressSpace::ZERO,
small_data_threshold_support: SmallDataThresholdSupport::DefaultForArch,
}
}