提交 50a2d47b 编写于 作者: T Tim Neumann

Support for the program data address space option

of LLVM's Target Datalayout.

https://llvm.org/docs/LangRef.html#data-layout
上级 653da4fd
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
use type_of::{LayoutLlvmExt, PointerKind}; use type_of::{LayoutLlvmExt, PointerKind};
use value::Value; use value::Value;
use rustc_target::abi::{LayoutOf, Size, TyLayout, Abi as LayoutAbi}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout, Abi as LayoutAbi};
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::layout; use rustc::ty::layout;
...@@ -276,6 +276,7 @@ fn adjust_for_abi(&mut self, ...@@ -276,6 +276,7 @@ fn adjust_for_abi(&mut self,
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
abi: Abi); abi: Abi);
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
fn llvm_cconv(&self) -> llvm::CallConv; fn llvm_cconv(&self) -> llvm::CallConv;
fn apply_attrs_llfn(&self, llfn: &'ll Value); fn apply_attrs_llfn(&self, llfn: &'ll Value);
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value); fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
...@@ -657,6 +658,13 @@ fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type { ...@@ -657,6 +658,13 @@ fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
} }
} }
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
unsafe {
llvm::LLVMPointerType(self.llvm_type(cx),
cx.data_layout().instruction_address_space as c_uint)
}
}
fn llvm_cconv(&self) -> llvm::CallConv { fn llvm_cconv(&self) -> llvm::CallConv {
match self.conv { match self.conv {
Conv::C => llvm::CCallConv, Conv::C => llvm::CCallConv,
......
...@@ -39,7 +39,7 @@ pub fn get_fn(self, bx: &Builder<'a, 'll, 'tcx>, ...@@ -39,7 +39,7 @@ pub fn get_fn(self, bx: &Builder<'a, 'll, 'tcx>,
// Load the data pointer from the object. // Load the data pointer from the object.
debug!("get_fn({:?}, {:?})", llvtable, self); debug!("get_fn({:?}, {:?})", llvtable, self);
let llvtable = bx.pointercast(llvtable, fn_ty.llvm_type(bx.cx).ptr_to().ptr_to()); let llvtable = bx.pointercast(llvtable, fn_ty.ptr_to_llvm_type(bx.cx).ptr_to());
let ptr_align = bx.tcx().data_layout.pointer_align; let ptr_align = bx.tcx().data_layout.pointer_align;
let ptr = bx.load(bx.inbounds_gep(llvtable, &[C_usize(bx.cx, self.0)]), ptr_align); let ptr = bx.load(bx.inbounds_gep(llvtable, &[C_usize(bx.cx, self.0)]), ptr_align);
bx.nonnull_metadata(ptr); bx.nonnull_metadata(ptr);
......
...@@ -234,6 +234,8 @@ pub fn set_struct_body(&'ll self, els: &[&'ll Type], packed: bool) { ...@@ -234,6 +234,8 @@ pub fn set_struct_body(&'ll self, els: &[&'ll Type], packed: bool) {
} }
pub fn ptr_to(&self) -> &Type { pub fn ptr_to(&self) -> &Type {
assert_ne!(self.kind(), TypeKind::Function,
"don't call ptr_to on function types, use ptr_to_llvm_type on FnType instead");
unsafe { unsafe {
llvm::LLVMPointerType(self, 0) llvm::LLVMPointerType(self, 0)
} }
......
...@@ -265,7 +265,7 @@ fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type { ...@@ -265,7 +265,7 @@ fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
ty::ParamEnv::reveal_all(), ty::ParamEnv::reveal_all(),
&sig, &sig,
); );
FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to() FnType::new(cx, sig, &[]).ptr_to_llvm_type(cx)
} }
_ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO) _ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO)
}; };
......
...@@ -35,7 +35,8 @@ pub struct TargetDataLayout { ...@@ -35,7 +35,8 @@ pub struct TargetDataLayout {
pub aggregate_align: Align, pub aggregate_align: Align,
/// Alignments for vector types. /// Alignments for vector types.
pub vector_align: Vec<(Size, Align)> pub vector_align: Vec<(Size, Align)>,
pub instruction_address_space: u32,
} }
impl Default for TargetDataLayout { impl Default for TargetDataLayout {
...@@ -57,13 +58,22 @@ fn default() -> TargetDataLayout { ...@@ -57,13 +58,22 @@ fn default() -> TargetDataLayout {
vector_align: vec![ vector_align: vec![
(Size::from_bits(64), Align::from_bits(64, 64).unwrap()), (Size::from_bits(64), Align::from_bits(64, 64).unwrap()),
(Size::from_bits(128), Align::from_bits(128, 128).unwrap()) (Size::from_bits(128), Align::from_bits(128, 128).unwrap())
] ],
instruction_address_space: 0,
} }
} }
} }
impl TargetDataLayout { impl TargetDataLayout {
pub fn parse(target: &Target) -> Result<TargetDataLayout, String> { pub fn parse(target: &Target) -> Result<TargetDataLayout, String> {
// Parse an address space index from a string.
let parse_address_space = |s: &str, cause: &str| {
s.parse::<u32>().map_err(|err| {
format!("invalid address space `{}` for `{}` in \"data-layout\": {}",
s, cause, err)
})
};
// Parse a bit count from a string. // Parse a bit count from a string.
let parse_bits = |s: &str, kind: &str, cause: &str| { let parse_bits = |s: &str, kind: &str, cause: &str| {
s.parse::<u64>().map_err(|err| { s.parse::<u64>().map_err(|err| {
...@@ -96,6 +106,9 @@ pub fn parse(target: &Target) -> Result<TargetDataLayout, String> { ...@@ -96,6 +106,9 @@ pub fn parse(target: &Target) -> Result<TargetDataLayout, String> {
match spec.split(':').collect::<Vec<_>>()[..] { match spec.split(':').collect::<Vec<_>>()[..] {
["e"] => dl.endian = Endian::Little, ["e"] => dl.endian = Endian::Little,
["E"] => dl.endian = Endian::Big, ["E"] => dl.endian = Endian::Big,
[p] if p.starts_with("P") => {
dl.instruction_address_space = parse_address_space(&p[1..], "P")?
}
["a", ref a..] => dl.aggregate_align = align(a, "a")?, ["a", ref a..] => dl.aggregate_align = align(a, "a")?,
["f32", ref a..] => dl.f32_align = align(a, "f32")?, ["f32", ref a..] => dl.f32_align = align(a, "f32")?,
["f64", ref a..] => dl.f64_align = align(a, "f64")?, ["f64", ref a..] => dl.f64_align = align(a, "f64")?,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册