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.
This commit is contained in:
@@ -849,6 +849,7 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
|
||||
/// Helper function to get the LLVM type for a Scalar. Pointers are returned as
|
||||
/// the equivalent integer type.
|
||||
fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Type {
|
||||
let dl = &cx.tcx.data_layout;
|
||||
match scalar.primitive() {
|
||||
Primitive::Int(Integer::I8, _) => cx.type_i8(),
|
||||
Primitive::Int(Integer::I16, _) => cx.type_i16(),
|
||||
@@ -856,7 +857,8 @@ fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Ty
|
||||
Primitive::Int(Integer::I64, _) => cx.type_i64(),
|
||||
Primitive::F32 => cx.type_f32(),
|
||||
Primitive::F64 => cx.type_f64(),
|
||||
Primitive::Pointer => cx.type_isize(),
|
||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||
Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -868,6 +870,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
|
||||
reg: InlineAsmRegClass,
|
||||
layout: &TyAndLayout<'tcx>,
|
||||
) -> &'ll Value {
|
||||
let dl = &bx.tcx.data_layout;
|
||||
match (reg, layout.abi) {
|
||||
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
|
||||
if let Primitive::Int(Integer::I8, _) = s.primitive() {
|
||||
@@ -881,8 +884,10 @@ fn llvm_fixup_input<'ll, 'tcx>(
|
||||
let elem_ty = llvm_asm_scalar_type(bx.cx, s);
|
||||
let count = 16 / layout.size.bytes();
|
||||
let vec_ty = bx.cx.type_vector(elem_ty, count);
|
||||
if let Primitive::Pointer = s.primitive() {
|
||||
value = bx.ptrtoint(value, bx.cx.type_isize());
|
||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||
if let Primitive::Pointer(_) = s.primitive() {
|
||||
let t = bx.type_from_integer(dl.ptr_sized_integer());
|
||||
value = bx.ptrtoint(value, t);
|
||||
}
|
||||
bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
|
||||
}
|
||||
@@ -958,7 +963,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
|
||||
}
|
||||
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s)) => {
|
||||
value = bx.extract_element(value, bx.const_i32(0));
|
||||
if let Primitive::Pointer = s.primitive() {
|
||||
if let Primitive::Pointer(_) = s.primitive() {
|
||||
value = bx.inttoptr(value, layout.llvm_type(bx.cx));
|
||||
}
|
||||
value
|
||||
|
||||
@@ -511,7 +511,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
bx.range_metadata(load, scalar.valid_range(bx));
|
||||
}
|
||||
}
|
||||
abi::Pointer => {
|
||||
abi::Pointer(_) => {
|
||||
if !scalar.valid_range(bx).contains(0) {
|
||||
bx.nonnull_metadata(load);
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
Scalar::Int(int) => {
|
||||
let data = int.assert_bits(layout.size(self));
|
||||
let llval = self.const_uint_big(self.type_ix(bitsize), data);
|
||||
if layout.primitive() == Pointer {
|
||||
if matches!(layout.primitive(), Pointer(_)) {
|
||||
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
|
||||
} else {
|
||||
self.const_bitcast(llval, llty)
|
||||
@@ -284,7 +284,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
1,
|
||||
)
|
||||
};
|
||||
if layout.primitive() != Pointer {
|
||||
if !matches!(layout.primitive(), Pointer(_)) {
|
||||
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
|
||||
} else {
|
||||
self.const_bitcast(llval, llty)
|
||||
|
||||
@@ -111,7 +111,7 @@ pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<
|
||||
&cx.tcx,
|
||||
),
|
||||
Scalar::Initialized {
|
||||
value: Primitive::Pointer,
|
||||
value: Primitive::Pointer(address_space),
|
||||
valid_range: WrappingRange::full(dl.pointer_size),
|
||||
},
|
||||
cx.type_i8p_ext(address_space),
|
||||
|
||||
@@ -122,7 +122,8 @@ fn tag_base_type<'ll, 'tcx>(
|
||||
Primitive::Int(t, _) => t,
|
||||
Primitive::F32 => Integer::I32,
|
||||
Primitive::F64 => Integer::I64,
|
||||
Primitive::Pointer => {
|
||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||
Primitive::Pointer(_) => {
|
||||
// If the niche is the NULL value of a reference, then `discr_enum_ty` will be
|
||||
// a RawPtr. CodeView doesn't know what to do with enums whose base type is a
|
||||
// pointer so we fix this up to just be `usize`.
|
||||
|
||||
@@ -149,7 +149,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
emit_va_arg(self, args[0], ret_ty)
|
||||
}
|
||||
}
|
||||
Primitive::F64 | Primitive::Pointer => {
|
||||
Primitive::F64 | Primitive::Pointer(_) => {
|
||||
emit_va_arg(self, args[0], ret_ty)
|
||||
}
|
||||
// `va_arg` should never be used with the return type f32.
|
||||
|
||||
@@ -7,7 +7,7 @@ use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitable};
|
||||
use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
|
||||
use rustc_target::abi::{Abi, Align, FieldsShape};
|
||||
use rustc_target::abi::{Int, Pointer, F32, F64};
|
||||
use rustc_target::abi::{PointeeInfo, Scalar, Size, TyAbiInterface, Variants};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@@ -312,14 +312,13 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
|
||||
Int(i, _) => cx.type_from_integer(i),
|
||||
F32 => cx.type_f32(),
|
||||
F64 => cx.type_f64(),
|
||||
Pointer => {
|
||||
Pointer(address_space) => {
|
||||
// If we know the alignment, pick something better than i8.
|
||||
let (pointee, address_space) =
|
||||
if let Some(pointee) = self.pointee_info_at(cx, offset) {
|
||||
(cx.type_pointee_for_align(pointee.align), pointee.address_space)
|
||||
} else {
|
||||
(cx.type_i8(), AddressSpace::DATA)
|
||||
};
|
||||
let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
|
||||
cx.type_pointee_for_align(pointee.align)
|
||||
} else {
|
||||
cx.type_i8()
|
||||
};
|
||||
cx.type_ptr_to_ext(pointee, address_space)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user