Skip to content

Commit 009192b

Browse files
abi: add AddressSpace field to Primitive::Pointer
...and remove it from `PointeeInfo`, which isn't meant for this. There are still various places (marked with FIXMEs) that assume all pointers have the same size and alignment. Fixing this requires parsing non-default address spaces in the data layout string, which will be done in a followup.
1 parent 96f8f99 commit 009192b

File tree

26 files changed

+218
-173
lines changed

26 files changed

+218
-173
lines changed

compiler/rustc_abi/src/lib.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ impl TargetDataLayout {
267267
["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?,
268268
["f32", ref a @ ..] => dl.f32_align = align(a, "f32")?,
269269
["f64", ref a @ ..] => dl.f64_align = align(a, "f64")?,
270+
// FIXME(erikdesjardins): we should be parsing nonzero address spaces
271+
// this will require replacing TargetDataLayout::{pointer_size,pointer_align}
272+
// with e.g. `fn pointer_size_in(AddressSpace)`
270273
[p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => {
271274
dl.pointer_size = size(s, p)?;
272275
dl.pointer_align = align(a, p)?;
@@ -861,7 +864,7 @@ pub enum Primitive {
861864
Int(Integer, bool),
862865
F32,
863866
F64,
864-
Pointer,
867+
Pointer(AddressSpace),
865868
}
866869

867870
impl Primitive {
@@ -872,7 +875,10 @@ impl Primitive {
872875
Int(i, _) => i.size(),
873876
F32 => Size::from_bits(32),
874877
F64 => Size::from_bits(64),
875-
Pointer => dl.pointer_size,
878+
// FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
879+
// different address spaces can have different sizes
880+
// (but TargetDataLayout doesn't currently parse that part of the DL string)
881+
Pointer(_) => dl.pointer_size,
876882
}
877883
}
878884

@@ -883,14 +889,12 @@ impl Primitive {
883889
Int(i, _) => i.align(dl),
884890
F32 => dl.f32_align,
885891
F64 => dl.f64_align,
886-
Pointer => dl.pointer_align,
892+
// FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
893+
// different address spaces can have different alignments
894+
// (but TargetDataLayout doesn't currently parse that part of the DL string)
895+
Pointer(_) => dl.pointer_align,
887896
}
888897
}
889-
890-
#[inline]
891-
pub fn is_ptr(self) -> bool {
892-
matches!(self, Pointer)
893-
}
894898
}
895899

896900
/// Inclusive wrap-around range of valid values, that is, if
@@ -1176,7 +1180,8 @@ impl FieldsShape {
11761180
/// An identifier that specifies the address space that some operation
11771181
/// should operate on. Special address spaces have an effect on code generation,
11781182
/// depending on the target and the address spaces it implements.
1179-
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
1183+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1184+
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
11801185
pub struct AddressSpace(pub u32);
11811186

11821187
impl AddressSpace {
@@ -1456,7 +1461,6 @@ pub struct PointeeInfo {
14561461
pub size: Size,
14571462
pub align: Align,
14581463
pub safe: Option<PointerKind>,
1459-
pub address_space: AddressSpace,
14601464
}
14611465

14621466
/// Used in `might_permit_raw_init` to indicate the kind of initialisation

compiler/rustc_codegen_cranelift/src/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type {
3535
},
3636
Primitive::F32 => types::F32,
3737
Primitive::F64 => types::F64,
38-
Primitive::Pointer => pointer_ty(tcx),
38+
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
39+
Primitive::Pointer(_) => pointer_ty(tcx),
3940
}
4041
}
4142

compiler/rustc_codegen_gcc/src/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
709709
bx.range_metadata(load, vr);
710710
}
711711
}
712-
abi::Pointer if vr.start < vr.end && !vr.contains(0) => {
712+
abi::Pointer(_) if vr.start < vr.end && !vr.contains(0) => {
713713
bx.nonnull_metadata(load);
714714
}
715715
_ => {}

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
211211
let base_addr = self.const_bitcast(base_addr, self.usize_type);
212212
let offset = self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64);
213213
let ptr = self.const_bitcast(base_addr + offset, ptr_type);
214-
if layout.primitive() != Pointer {
214+
if !matches!(layout.primitive(), Pointer(_)) {
215215
self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
216216
}
217217
else {

compiler/rustc_codegen_gcc/src/consts.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}
77
use rustc_middle::mir::mono::MonoItem;
88
use rustc_middle::ty::{self, Instance, Ty};
99
use rustc_middle::ty::layout::LayoutOf;
10-
use rustc_middle::mir::interpret::{self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint};
10+
use rustc_middle::mir::interpret::{self, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar as InterpScalar, read_target_uint};
1111
use rustc_span::def_id::DefId;
12-
use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange};
12+
use rustc_target::abi::{self, AddressSpace, Align, HasDataLayout, Primitive, Size, WrappingRange};
1313

1414
use crate::base;
1515
use crate::context::CodegenCx;
@@ -322,13 +322,21 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl
322322
)
323323
.expect("const_alloc_to_llvm: could not read relocation pointer")
324324
as u64;
325+
326+
let address_space = match cx.tcx.global_alloc(alloc_id) {
327+
GlobalAlloc::Function(..) => cx.data_layout().instruction_address_space,
328+
GlobalAlloc::Static(..) | GlobalAlloc::Memory(..) | GlobalAlloc::VTable(..) => {
329+
AddressSpace::DATA
330+
}
331+
};
332+
325333
llvals.push(cx.scalar_to_backend(
326334
InterpScalar::from_pointer(
327335
interpret::Pointer::new(alloc_id, Size::from_bytes(ptr_offset)),
328336
&cx.tcx,
329337
),
330-
abi::Scalar::Initialized { value: Primitive::Pointer, valid_range: WrappingRange::full(dl.pointer_size) },
331-
cx.type_i8p(),
338+
abi::Scalar::Initialized { value: Primitive::Pointer(address_space), valid_range: WrappingRange::full(dl.pointer_size) },
339+
cx.type_i8p_ext(address_space),
332340
));
333341
next_offset = offset + pointer_size;
334342
}

compiler/rustc_codegen_gcc/src/type_of.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
253253
Int(i, false) => cx.type_from_unsigned_integer(i),
254254
F32 => cx.type_f32(),
255255
F64 => cx.type_f64(),
256-
Pointer => {
256+
Pointer(address_space) => {
257257
// If we know the alignment, pick something better than i8.
258258
let pointee =
259259
if let Some(pointee) = self.pointee_info_at(cx, offset) {
@@ -262,7 +262,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
262262
else {
263263
cx.type_i8()
264264
};
265-
cx.type_ptr_to(pointee)
265+
cx.type_ptr_to_ext(pointee, address_space)
266266
}
267267
}
268268
}

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -849,14 +849,16 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
849849
/// Helper function to get the LLVM type for a Scalar. Pointers are returned as
850850
/// the equivalent integer type.
851851
fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Type {
852+
let dl = &cx.tcx.data_layout;
852853
match scalar.primitive() {
853854
Primitive::Int(Integer::I8, _) => cx.type_i8(),
854855
Primitive::Int(Integer::I16, _) => cx.type_i16(),
855856
Primitive::Int(Integer::I32, _) => cx.type_i32(),
856857
Primitive::Int(Integer::I64, _) => cx.type_i64(),
857858
Primitive::F32 => cx.type_f32(),
858859
Primitive::F64 => cx.type_f64(),
859-
Primitive::Pointer => cx.type_isize(),
860+
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
861+
Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
860862
_ => unreachable!(),
861863
}
862864
}
@@ -868,6 +870,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
868870
reg: InlineAsmRegClass,
869871
layout: &TyAndLayout<'tcx>,
870872
) -> &'ll Value {
873+
let dl = &bx.tcx.data_layout;
871874
match (reg, layout.abi) {
872875
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
873876
if let Primitive::Int(Integer::I8, _) = s.primitive() {
@@ -881,8 +884,10 @@ fn llvm_fixup_input<'ll, 'tcx>(
881884
let elem_ty = llvm_asm_scalar_type(bx.cx, s);
882885
let count = 16 / layout.size.bytes();
883886
let vec_ty = bx.cx.type_vector(elem_ty, count);
884-
if let Primitive::Pointer = s.primitive() {
885-
value = bx.ptrtoint(value, bx.cx.type_isize());
887+
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
888+
if let Primitive::Pointer(_) = s.primitive() {
889+
let t = bx.type_from_integer(dl.ptr_sized_integer());
890+
value = bx.ptrtoint(value, t);
886891
}
887892
bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
888893
}
@@ -958,7 +963,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
958963
}
959964
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
960965
value = bx.extract_element(value, bx.const_i32(0));
961-
if let Primitive::Pointer = s.primitive() {
966+
if let Primitive::Pointer(_) = s.primitive() {
962967
value = bx.inttoptr(value, layout.llvm_type(bx.cx));
963968
}
964969
value

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
511511
bx.range_metadata(load, scalar.valid_range(bx));
512512
}
513513
}
514-
abi::Pointer => {
514+
abi::Pointer(_) => {
515515
if !scalar.valid_range(bx).contains(0) {
516516
bx.nonnull_metadata(load);
517517
}

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
236236
Scalar::Int(int) => {
237237
let data = int.assert_bits(layout.size(self));
238238
let llval = self.const_uint_big(self.type_ix(bitsize), data);
239-
if layout.primitive() == Pointer {
239+
if matches!(layout.primitive(), Pointer(_)) {
240240
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
241241
} else {
242242
self.const_bitcast(llval, llty)
@@ -284,7 +284,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
284284
1,
285285
)
286286
};
287-
if layout.primitive() != Pointer {
287+
if !matches!(layout.primitive(), Pointer(_)) {
288288
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
289289
} else {
290290
self.const_bitcast(llval, llty)

compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
111111
&cx.tcx,
112112
),
113113
Scalar::Initialized {
114-
value: Primitive::Pointer,
114+
value: Primitive::Pointer(address_space),
115115
valid_range: WrappingRange::full(dl.pointer_size),
116116
},
117117
cx.type_i8p_ext(address_space),

0 commit comments

Comments
 (0)