Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #143182 - xdoardo:more-addrspace, r=workingjubilee
Allow custom default address spaces and parse `p-` specifications in the datalayout string
Some targets, such as CHERI, use as default an address space different from the "normal" default address space `0` (in the case of CHERI, [200 is used](https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-877.pdf)). Currently, `rustc` does not allow to specify custom address spaces and does not take into consideration [`p-` specifications in the datalayout string](https://llvm.org/docs/LangRef.html#langref-datalayout).
This patch tries to mitigate these problems by allowing targets to define a custom default address space (while keeping the default value to address space `0`) and adding the code to parse the `p-` specifications in `rustc_abi`. The main changes are that `TargetDataLayout` now uses functions to refer to pointer-related informations, instead of having specific fields for the size and alignment of pointers in the default address space; furthermore, the two `pointer_size` and `pointer_align` fields in `TargetDataLayout` are replaced with an `FxHashMap` that holds info for all the possible address spaces, as parsed by the `p-` specifications.
The potential performance drawbacks of not having ad-hoc fields for the default address space will be tested in this PR's CI run.
r? workingjubilee
| -rw-r--r-- | crates/hir-ty/src/layout.rs | 4 | ||||
| -rw-r--r-- | crates/hir-ty/src/layout/target.rs | 5 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/eval.rs | 2 |
3 files changed, 6 insertions, 5 deletions
diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs index 3fa2bfbd1b..107da6a5af 100644 --- a/crates/hir-ty/src/layout.rs +++ b/crates/hir-ty/src/layout.rs @@ -261,7 +261,7 @@ pub fn layout_of_ty_query( } // Potentially-wide pointers. TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => { - let mut data_ptr = scalar_unit(dl, Primitive::Pointer(AddressSpace::DATA)); + let mut data_ptr = scalar_unit(dl, Primitive::Pointer(AddressSpace::ZERO)); if matches!(ty.kind(Interner), TyKind::Ref(..)) { data_ptr.valid_range_mut().start = 1; } @@ -285,7 +285,7 @@ pub fn layout_of_ty_query( scalar_unit(dl, Primitive::Int(dl.ptr_sized_integer(), false)) } TyKind::Dyn(..) => { - let mut vtable = scalar_unit(dl, Primitive::Pointer(AddressSpace::DATA)); + let mut vtable = scalar_unit(dl, Primitive::Pointer(AddressSpace::ZERO)); vtable.valid_range_mut().start = 1; vtable } diff --git a/crates/hir-ty/src/layout/target.rs b/crates/hir-ty/src/layout/target.rs index e1e1c44996..88c33eccca 100644 --- a/crates/hir-ty/src/layout/target.rs +++ b/crates/hir-ty/src/layout/target.rs @@ -2,7 +2,7 @@ use base_db::Crate; use hir_def::layout::TargetDataLayout; -use rustc_abi::{AlignFromBytesError, TargetDataLayoutErrors}; +use rustc_abi::{AlignFromBytesError, TargetDataLayoutErrors, AddressSpace}; use triomphe::Arc; use crate::db::HirDatabase; @@ -12,7 +12,7 @@ pub fn target_data_layout_query( krate: Crate, ) -> Result<Arc<TargetDataLayout>, Arc<str>> { match &krate.workspace_data(db).data_layout { - Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it) { + Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it, AddressSpace::ZERO) { Ok(it) => Ok(Arc::new(it)), Err(e) => { Err(match e { @@ -39,6 +39,7 @@ pub fn target_data_layout_query( target, } => format!(r#"inconsistent target specification: "data-layout" claims pointers are {pointer_size}-bit, while "target-pointer-width" is `{target}`"#), TargetDataLayoutErrors::InvalidBitsSize { err } => err, + TargetDataLayoutErrors::UnknownPointerSpecification { err } => format!(r#"use of unknown pointer specifer in "data-layout": {err}"#), }.into()) } }, diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 1ec55a8209..55fada1436 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -630,7 +630,7 @@ impl Evaluator<'_> { Ok(target_data_layout) => target_data_layout, Err(e) => return Err(MirEvalError::TargetDataLayoutNotAvailable(e)), }; - let cached_ptr_size = target_data_layout.pointer_size.bytes_usize(); + let cached_ptr_size = target_data_layout.pointer_size().bytes_usize(); Ok(Evaluator { target_data_layout, stack: vec![0], |