Skip to content

Commit 9b8f902

Browse files
committed
Auto merge of #54993 - TimNN:pda-tdl, r=eddyb
Support for the program data address space option of LLVM's Target Datalayout This was introduced recently (specifically, for AVR, cc @dylanmckay). (I came up with this when attempting to run [avr-rust](https://github.com/avr-rust/rust) rebased on the latest [rust-lang](https://github.com/rust-lang/rust) commits. If this requires a different design, some additional discussions, or is not something to pursue right now, I'd be happy to close this PR). Note that this somewhat overlaps with @DiamondLovesYou's #51576, I think, although the implementation here is significantly simpler: Since the address space applies to _all_ program data, we can just check the pointee's type whenever we create an LLVM pointer type. If it is a function we use the program data address space; if not we use the default address space. cc @eddyb, who has been reviewing #51576 Ref: https://llvm.org/docs/LangRef.html#data-layout
2 parents 6408162 + 50a2d47 commit 9b8f902

File tree

5 files changed

+28
-5
lines changed

5 files changed

+28
-5
lines changed

Diff for: src/librustc_codegen_llvm/abi.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use type_::Type;
1919
use type_of::{LayoutLlvmExt, PointerKind};
2020
use value::Value;
2121

22-
use rustc_target::abi::{LayoutOf, Size, TyLayout, Abi as LayoutAbi};
22+
use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout, Abi as LayoutAbi};
2323
use rustc::ty::{self, Ty};
2424
use rustc::ty::layout;
2525

@@ -277,6 +277,7 @@ pub trait FnTypeExt<'tcx> {
277277
cx: &CodegenCx<'ll, 'tcx>,
278278
abi: Abi);
279279
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
280+
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
280281
fn llvm_cconv(&self) -> llvm::CallConv;
281282
fn apply_attrs_llfn(&self, llfn: &'ll Value);
282283
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
@@ -658,6 +659,13 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
658659
}
659660
}
660661

662+
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
663+
unsafe {
664+
llvm::LLVMPointerType(self.llvm_type(cx),
665+
cx.data_layout().instruction_address_space as c_uint)
666+
}
667+
}
668+
661669
fn llvm_cconv(&self) -> llvm::CallConv {
662670
match self.conv {
663671
Conv::C => llvm::CCallConv,

Diff for: src/librustc_codegen_llvm/meth.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl<'a, 'tcx> VirtualIndex {
3939
// Load the data pointer from the object.
4040
debug!("get_fn({:?}, {:?})", llvtable, self);
4141

42-
let llvtable = bx.pointercast(llvtable, fn_ty.llvm_type(bx.cx).ptr_to().ptr_to());
42+
let llvtable = bx.pointercast(llvtable, fn_ty.ptr_to_llvm_type(bx.cx).ptr_to());
4343
let ptr_align = bx.tcx().data_layout.pointer_align;
4444
let ptr = bx.load(bx.inbounds_gep(llvtable, &[C_usize(bx.cx, self.0)]), ptr_align);
4545
bx.nonnull_metadata(ptr);

Diff for: src/librustc_codegen_llvm/type_.rs

+2
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ impl Type {
234234
}
235235

236236
pub fn ptr_to(&self) -> &Type {
237+
assert_ne!(self.kind(), TypeKind::Function,
238+
"don't call ptr_to on function types, use ptr_to_llvm_type on FnType instead");
237239
unsafe {
238240
llvm::LLVMPointerType(self, 0)
239241
}

Diff for: src/librustc_codegen_llvm/type_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
265265
ty::ParamEnv::reveal_all(),
266266
&sig,
267267
);
268-
FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to()
268+
FnType::new(cx, sig, &[]).ptr_to_llvm_type(cx)
269269
}
270270
_ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO)
271271
};

Diff for: src/librustc_target/abi/mod.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ pub struct TargetDataLayout {
3535
pub aggregate_align: Align,
3636

3737
/// Alignments for vector types.
38-
pub vector_align: Vec<(Size, Align)>
38+
pub vector_align: Vec<(Size, Align)>,
39+
pub instruction_address_space: u32,
3940
}
4041

4142
impl Default for TargetDataLayout {
@@ -57,13 +58,22 @@ impl Default for TargetDataLayout {
5758
vector_align: vec![
5859
(Size::from_bits(64), Align::from_bits(64, 64).unwrap()),
5960
(Size::from_bits(128), Align::from_bits(128, 128).unwrap())
60-
]
61+
],
62+
instruction_address_space: 0,
6163
}
6264
}
6365
}
6466

6567
impl TargetDataLayout {
6668
pub fn parse(target: &Target) -> Result<TargetDataLayout, String> {
69+
// Parse an address space index from a string.
70+
let parse_address_space = |s: &str, cause: &str| {
71+
s.parse::<u32>().map_err(|err| {
72+
format!("invalid address space `{}` for `{}` in \"data-layout\": {}",
73+
s, cause, err)
74+
})
75+
};
76+
6777
// Parse a bit count from a string.
6878
let parse_bits = |s: &str, kind: &str, cause: &str| {
6979
s.parse::<u64>().map_err(|err| {
@@ -96,6 +106,9 @@ impl TargetDataLayout {
96106
match spec.split(':').collect::<Vec<_>>()[..] {
97107
["e"] => dl.endian = Endian::Little,
98108
["E"] => dl.endian = Endian::Big,
109+
[p] if p.starts_with("P") => {
110+
dl.instruction_address_space = parse_address_space(&p[1..], "P")?
111+
}
99112
["a", ref a..] => dl.aggregate_align = align(a, "a")?,
100113
["f32", ref a..] => dl.f32_align = align(a, "f32")?,
101114
["f64", ref a..] => dl.f64_align = align(a, "f64")?,

0 commit comments

Comments
 (0)