mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
rustc_trans: query LLVM types from a layout instead of a Ty.
This commit is contained in:
parent
1477119344
commit
3fd6b00082
@ -32,6 +32,7 @@ use cabi_nvptx64;
|
||||
use cabi_hexagon;
|
||||
use mir::lvalue::LvalueRef;
|
||||
use type_::Type;
|
||||
use type_of::LayoutLlvmExt;
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::ty::{self, Ty};
|
||||
@ -506,7 +507,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
|
||||
/// Get the LLVM type for an lvalue of the original Rust type of
|
||||
/// this argument/return, i.e. the result of `type_of::type_of`.
|
||||
pub fn memory_ty(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
|
||||
ccx.llvm_type_of(self.layout.ty)
|
||||
self.layout.llvm_type(ccx)
|
||||
}
|
||||
|
||||
/// Store a direct/indirect value described by this ArgType into a
|
||||
@ -934,7 +935,7 @@ impl<'a, 'tcx> FnType<'tcx> {
|
||||
} else if let Some(cast) = self.ret.cast {
|
||||
cast.llvm_type(ccx)
|
||||
} else {
|
||||
ccx.immediate_llvm_type_of(self.ret.layout.ty)
|
||||
self.ret.layout.immediate_llvm_type(ccx)
|
||||
};
|
||||
|
||||
{
|
||||
@ -952,7 +953,7 @@ impl<'a, 'tcx> FnType<'tcx> {
|
||||
} else if let Some(cast) = arg.cast {
|
||||
cast.llvm_type(ccx)
|
||||
} else {
|
||||
ccx.immediate_llvm_type_of(arg.layout.ty)
|
||||
arg.layout.immediate_llvm_type(ccx)
|
||||
};
|
||||
|
||||
llargument_tys.push(llarg_ty);
|
||||
|
@ -13,6 +13,7 @@
|
||||
use llvm::{self, ValueRef};
|
||||
use common::*;
|
||||
use type_::Type;
|
||||
use type_of::LayoutLlvmExt;
|
||||
use builder::Builder;
|
||||
|
||||
use rustc::hir;
|
||||
@ -44,7 +45,7 @@ pub fn trans_inline_asm<'a, 'tcx>(
|
||||
if out.is_indirect {
|
||||
indirect_outputs.push(lvalue.load(bcx).immediate());
|
||||
} else {
|
||||
output_types.push(bcx.ccx.llvm_type_of(lvalue.layout.ty));
|
||||
output_types.push(lvalue.layout.llvm_type(bcx.ccx));
|
||||
}
|
||||
}
|
||||
if !indirect_outputs.is_empty() {
|
||||
|
@ -40,7 +40,7 @@ use rustc::middle::lang_items::StartFnLangItem;
|
||||
use rustc::middle::trans::{Linkage, Visibility, Stats};
|
||||
use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{Align, FullLayout};
|
||||
use rustc::ty::layout::{self, Align, FullLayout, LayoutOf};
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::dep_graph::{DepNode, DepKind, DepConstructor};
|
||||
use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
|
||||
@ -68,7 +68,7 @@ use symbol_names_test;
|
||||
use time_graph;
|
||||
use trans_item::{TransItem, BaseTransItemExt, TransItemExt, DefPathBasedNames};
|
||||
use type_::Type;
|
||||
use type_of;
|
||||
use type_of::{self, LayoutLlvmExt};
|
||||
use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet};
|
||||
use CrateInfo;
|
||||
|
||||
@ -228,13 +228,13 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
|
||||
(&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }),
|
||||
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
||||
assert!(bcx.ccx.shared().type_is_sized(a));
|
||||
let ptr_ty = bcx.ccx.llvm_type_of(b).ptr_to();
|
||||
let ptr_ty = bcx.ccx.layout_of(b).llvm_type(bcx.ccx).ptr_to();
|
||||
(bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None))
|
||||
}
|
||||
(&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
|
||||
let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty());
|
||||
assert!(bcx.ccx.shared().type_is_sized(a));
|
||||
let ptr_ty = bcx.ccx.llvm_type_of(b).ptr_to();
|
||||
let ptr_ty = bcx.ccx.layout_of(b).llvm_type(bcx.ccx).ptr_to();
|
||||
(bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None))
|
||||
}
|
||||
_ => bug!("unsize_thin_ptr: called on bad types"),
|
||||
@ -371,8 +371,8 @@ pub fn from_immediate(bcx: &Builder, val: ValueRef) -> ValueRef {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_immediate(bcx: &Builder, val: ValueRef, ty: Ty) -> ValueRef {
|
||||
if ty.is_bool() {
|
||||
pub fn to_immediate(bcx: &Builder, val: ValueRef, layout: layout::FullLayout) -> ValueRef {
|
||||
if let layout::Abi::Scalar(layout::Int(layout::I1, _)) = layout.abi {
|
||||
bcx.trunc(val, Type::i1(bcx.ccx))
|
||||
} else {
|
||||
val
|
||||
|
@ -20,8 +20,11 @@ use consts;
|
||||
use declare;
|
||||
use llvm::{self, ValueRef};
|
||||
use monomorphize::Instance;
|
||||
use type_of::LayoutLlvmExt;
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, TypeFoldable};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use rustc::traits;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc_back::PanicStrategy;
|
||||
@ -55,7 +58,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
// Create a fn pointer with the substituted signature.
|
||||
let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(ccx, fn_ty));
|
||||
let llptrty = ccx.llvm_type_of(fn_ptr_ty);
|
||||
let llptrty = ccx.layout_of(fn_ptr_ty).llvm_type(ccx);
|
||||
|
||||
let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
|
||||
// This is subtle and surprising, but sometimes we have to bitcast
|
||||
|
@ -24,6 +24,7 @@ use builder::Builder;
|
||||
use consts;
|
||||
use declare;
|
||||
use type_::Type;
|
||||
use type_of::LayoutLlvmExt;
|
||||
use value::Value;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
@ -254,7 +255,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
|
||||
pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
|
||||
let len = s.len();
|
||||
let cs = consts::ptrcast(C_cstr(cx, s, false),
|
||||
cx.llvm_type_of(cx.tcx().mk_str()).ptr_to());
|
||||
cx.layout_of(cx.tcx().mk_str()).llvm_type(cx).ptr_to());
|
||||
let empty = C_array(Type::i8(cx), &[]);
|
||||
assert_eq!(abi::FAT_PTR_ADDR, 0);
|
||||
assert_eq!(abi::FAT_PTR_EXTRA, 1);
|
||||
|
@ -21,8 +21,9 @@ use common::{self, CrateContext, val_ty};
|
||||
use declare;
|
||||
use monomorphize::Instance;
|
||||
use type_::Type;
|
||||
use type_of::LayoutLlvmExt;
|
||||
use rustc::ty;
|
||||
use rustc::ty::layout::Align;
|
||||
use rustc::ty::layout::{Align, LayoutOf};
|
||||
|
||||
use rustc::hir;
|
||||
|
||||
@ -112,7 +113,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
||||
let ty = common::instance_ty(ccx.tcx(), &instance);
|
||||
let g = if let Some(id) = ccx.tcx().hir.as_local_node_id(def_id) {
|
||||
|
||||
let llty = ccx.llvm_type_of(ty);
|
||||
let llty = ccx.layout_of(ty).llvm_type(ccx);
|
||||
let (g, attrs) = match ccx.tcx().hir.get(id) {
|
||||
hir_map::NodeItem(&hir::Item {
|
||||
ref attrs, span, node: hir::ItemStatic(..), ..
|
||||
@ -157,7 +158,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
||||
}
|
||||
};
|
||||
let llty2 = match ty.sty {
|
||||
ty::TyRawPtr(ref mt) => ccx.llvm_type_of(mt.ty),
|
||||
ty::TyRawPtr(ref mt) => ccx.layout_of(mt.ty).llvm_type(ccx),
|
||||
_ => {
|
||||
ccx.sess().span_fatal(span, "must have type `*const T` or `*mut T`");
|
||||
}
|
||||
@ -206,7 +207,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
||||
|
||||
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
|
||||
// FIXME(nagisa): investigate whether it can be changed into define_global
|
||||
let g = declare::declare_global(ccx, &sym, ccx.llvm_type_of(ty));
|
||||
let g = declare::declare_global(ccx, &sym, ccx.layout_of(ty).llvm_type(ccx));
|
||||
// Thread-local statics in some other crate need to *always* be linked
|
||||
// against in a thread-local fashion, so we need to be sure to apply the
|
||||
// thread-local attribute locally if it was present remotely. If we
|
||||
@ -266,7 +267,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
let instance = Instance::mono(ccx.tcx(), def_id);
|
||||
let ty = common::instance_ty(ccx.tcx(), &instance);
|
||||
let llty = ccx.llvm_type_of(ty);
|
||||
let llty = ccx.layout_of(ty).llvm_type(ccx);
|
||||
let g = if val_llty == llty {
|
||||
g
|
||||
} else {
|
||||
|
@ -24,6 +24,8 @@ use monomorphize::Instance;
|
||||
|
||||
use partitioning::CodegenUnit;
|
||||
use type_::Type;
|
||||
use type_of::LayoutLlvmExt;
|
||||
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc::middle::trans::Stats;
|
||||
use rustc_data_structures::stable_hasher::StableHashingContextProvider;
|
||||
@ -397,7 +399,7 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
||||
let mut str_slice_ty = Type::named_struct(&dummy_ccx, "str_slice");
|
||||
str_slice_ty.set_struct_body(&[
|
||||
Type::array(&Type::i8(&dummy_ccx), 0),
|
||||
dummy_ccx.llvm_type_of(shared.tcx.mk_str()).ptr_to(),
|
||||
dummy_ccx.layout_of(shared.tcx.mk_str()).llvm_type(&dummy_ccx).ptr_to(),
|
||||
Type::array(&Type::i8(&dummy_ccx), 0),
|
||||
Type::isize(&dummy_ccx),
|
||||
Type::array(&Type::i8(&dummy_ccx), 0)
|
||||
|
@ -21,6 +21,7 @@ use common::*;
|
||||
use declare;
|
||||
use glue;
|
||||
use type_::Type;
|
||||
use type_of::LayoutLlvmExt;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{HasDataLayout, LayoutOf};
|
||||
use rustc::hir;
|
||||
@ -104,7 +105,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
let ret_ty = sig.output();
|
||||
let name = &*tcx.item_name(def_id);
|
||||
|
||||
let llret_ty = ccx.llvm_type_of(ret_ty);
|
||||
let llret_ty = ccx.layout_of(ret_ty).llvm_type(ccx);
|
||||
let result = LvalueRef::new_sized(llresult, fn_ty.ret.layout, Alignment::AbiAligned);
|
||||
|
||||
let simple = get_simple_intrinsic(ccx, name);
|
||||
@ -243,7 +244,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
unsafe {
|
||||
llvm::LLVMSetAlignment(load, ccx.align_of(tp_ty).abi() as u32);
|
||||
}
|
||||
to_immediate(bcx, load, tp_ty)
|
||||
to_immediate(bcx, load, ccx.layout_of(tp_ty))
|
||||
},
|
||||
"volatile_store" => {
|
||||
let tp_ty = substs.type_at(0);
|
||||
|
@ -662,7 +662,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
if arg.layout.ty == bcx.tcx().types.bool {
|
||||
llval = bcx.load_range_assert(llval, 0, 2, llvm::False, None);
|
||||
// We store bools as i8 so we need to truncate to i1.
|
||||
llval = base::to_immediate(bcx, llval, arg.layout.ty);
|
||||
llval = base::to_immediate(bcx, llval, arg.layout);
|
||||
} else if let Some(ty) = arg.cast {
|
||||
llval = bcx.load(bcx.pointercast(llval, ty.llvm_type(bcx.ccx).ptr_to()),
|
||||
(align | Alignment::Packed(arg.layout.align(bcx.ccx)))
|
||||
@ -682,45 +682,37 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
args: &[ArgType<'tcx>]) {
|
||||
let tuple = self.trans_operand(bcx, operand);
|
||||
|
||||
let arg_types = match tuple.layout.ty.sty {
|
||||
ty::TyTuple(ref tys, _) => tys,
|
||||
_ => span_bug!(self.mir.span,
|
||||
"bad final argument to \"rust-call\" fn {:?}", tuple.layout.ty)
|
||||
};
|
||||
|
||||
// Handle both by-ref and immediate tuples.
|
||||
match tuple.val {
|
||||
Ref(llval, align) => {
|
||||
let tuple_ptr = LvalueRef::new_sized(llval, tuple.layout, align);
|
||||
for n in 0..arg_types.len() {
|
||||
let field_ptr = tuple_ptr.project_field(bcx, n);
|
||||
self.trans_argument(bcx, field_ptr.load(bcx), llargs, &args[n]);
|
||||
for i in 0..tuple.layout.fields.count() {
|
||||
let field_ptr = tuple_ptr.project_field(bcx, i);
|
||||
self.trans_argument(bcx, field_ptr.load(bcx), llargs, &args[i]);
|
||||
}
|
||||
|
||||
}
|
||||
Immediate(llval) => {
|
||||
for (n, &ty) in arg_types.iter().enumerate() {
|
||||
let mut elem = bcx.extract_value(llval, tuple.layout.llvm_field_index(n));
|
||||
// Truncate bools to i1, if needed
|
||||
elem = base::to_immediate(bcx, elem, ty);
|
||||
for i in 0..tuple.layout.fields.count() {
|
||||
let field = tuple.layout.field(bcx.ccx, i);
|
||||
let elem = bcx.extract_value(llval, tuple.layout.llvm_field_index(i));
|
||||
// If the tuple is immediate, the elements are as well
|
||||
let op = OperandRef {
|
||||
val: Immediate(elem),
|
||||
layout: bcx.ccx.layout_of(ty),
|
||||
val: Immediate(base::to_immediate(bcx, elem, field)),
|
||||
layout: field,
|
||||
};
|
||||
self.trans_argument(bcx, op, llargs, &args[n]);
|
||||
self.trans_argument(bcx, op, llargs, &args[i]);
|
||||
}
|
||||
}
|
||||
Pair(a, b) => {
|
||||
let elems = [a, b];
|
||||
for (n, &ty) in arg_types.iter().enumerate() {
|
||||
let elem = base::to_immediate(bcx, elems[n], ty);
|
||||
for i in 0..tuple.layout.fields.count() {
|
||||
// Pair is always made up of immediates
|
||||
let op = OperandRef {
|
||||
val: Immediate(elem),
|
||||
layout: bcx.ccx.layout_of(ty),
|
||||
val: Immediate(elems[i]),
|
||||
layout: tuple.layout.field(bcx.ccx, i),
|
||||
};
|
||||
self.trans_argument(bcx, op, llargs, &args[n]);
|
||||
self.trans_argument(bcx, op, llargs, &args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -891,7 +883,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
src: &mir::Operand<'tcx>,
|
||||
dst: LvalueRef<'tcx>) {
|
||||
let src = self.trans_operand(bcx, src);
|
||||
let llty = bcx.ccx.llvm_type_of(src.layout.ty);
|
||||
let llty = src.layout.llvm_type(bcx.ccx);
|
||||
let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
|
||||
let align = src.layout.align(bcx.ccx).min(dst.layout.align(bcx.ccx));
|
||||
src.val.store(bcx,
|
||||
|
@ -87,7 +87,7 @@ impl<'a, 'tcx> Const<'tcx> {
|
||||
cv: &ConstVal,
|
||||
ty: Ty<'tcx>)
|
||||
-> Const<'tcx> {
|
||||
let llty = ccx.llvm_type_of(ty);
|
||||
let llty = ccx.layout_of(ty).llvm_type(ccx);
|
||||
let val = match *cv {
|
||||
ConstVal::Float(v) => {
|
||||
let bits = match v.ty {
|
||||
@ -139,7 +139,7 @@ impl<'a, 'tcx> Const<'tcx> {
|
||||
}
|
||||
|
||||
pub fn to_operand(&self, ccx: &CrateContext<'a, 'tcx>) -> OperandRef<'tcx> {
|
||||
let llty = ccx.immediate_llvm_type_of(self.ty);
|
||||
let llty = ccx.layout_of(self.ty).immediate_llvm_type(ccx);
|
||||
let llvalty = val_ty(self.llval);
|
||||
|
||||
let val = if llty == llvalty && common::type_is_imm_pair(ccx, self.ty) {
|
||||
@ -489,7 +489,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
let llelem = if iv < len as u128 {
|
||||
const_get_elt(base.llval, iv as u64)
|
||||
} else {
|
||||
C_undef(self.ccx.llvm_type_of(projected_ty))
|
||||
C_undef(self.ccx.layout_of(projected_ty).llvm_type(self.ccx))
|
||||
};
|
||||
|
||||
(Base::Value(llelem), ptr::null_mut())
|
||||
@ -543,7 +543,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
let elem_ty = array_ty.builtin_index().unwrap_or_else(|| {
|
||||
bug!("bad array type {:?}", array_ty)
|
||||
});
|
||||
let llunitty = self.ccx.llvm_type_of(elem_ty);
|
||||
let llunitty = self.ccx.layout_of(elem_ty).llvm_type(self.ccx);
|
||||
// If the array contains enums, an LLVM array won't work.
|
||||
let val = if fields.iter().all(|&f| val_ty(f) == llunitty) {
|
||||
C_array(llunitty, fields)
|
||||
@ -665,7 +665,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
|
||||
let unsized_ty = cast_ty.builtin_deref(true, ty::NoPreference)
|
||||
.expect("consts: unsizing got non-pointer target type").ty;
|
||||
let ptr_ty = self.ccx.llvm_type_of(unsized_ty).ptr_to();
|
||||
let ptr_ty = self.ccx.layout_of(unsized_ty).llvm_type(self.ccx).ptr_to();
|
||||
let base = consts::ptrcast(base, ptr_ty);
|
||||
let info = base::unsized_info(self.ccx, pointee_ty,
|
||||
unsized_ty, old_info);
|
||||
@ -681,7 +681,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
debug_assert!(common::type_is_immediate(self.ccx, cast_ty));
|
||||
let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast");
|
||||
let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
let ll_t_out = self.ccx.immediate_llvm_type_of(cast_ty);
|
||||
let ll_t_out = self.ccx.layout_of(cast_ty).immediate_llvm_type(self.ccx);
|
||||
let llval = operand.llval;
|
||||
let signed = match self.ccx.layout_of(operand.ty).abi {
|
||||
layout::Abi::Scalar(layout::Int(_, signed)) => signed,
|
||||
@ -734,7 +734,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||
} else { // cast to thin-ptr
|
||||
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
|
||||
// pointer-cast of that pointer to desired pointer type.
|
||||
let llcast_ty = self.ccx.immediate_llvm_type_of(cast_ty);
|
||||
let llcast_ty = self.ccx.layout_of(cast_ty)
|
||||
.immediate_llvm_type(self.ccx);
|
||||
consts::ptrcast(data_ptr, llcast_ty)
|
||||
}
|
||||
} else {
|
||||
@ -1041,7 +1042,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
|
||||
let result = result.unwrap_or_else(|_| {
|
||||
// We've errored, so we don't have to produce working code.
|
||||
let llty = bcx.ccx.llvm_type_of(ty);
|
||||
let llty = bcx.ccx.layout_of(ty).llvm_type(bcx.ccx);
|
||||
Const::new(C_undef(llty), ty)
|
||||
});
|
||||
|
||||
@ -1100,7 +1101,7 @@ fn trans_const_adt<'a, 'tcx>(
|
||||
_ => 0,
|
||||
};
|
||||
let discr_ty = l.field(ccx, 0).ty;
|
||||
let discr = C_int(ccx.llvm_type_of(discr_ty), discr as i64);
|
||||
let discr = C_int(ccx.layout_of(discr_ty).llvm_type(ccx), discr as i64);
|
||||
if let layout::Abi::Scalar(_) = l.abi {
|
||||
Const::new(discr, t)
|
||||
} else {
|
||||
@ -1130,7 +1131,7 @@ fn trans_const_adt<'a, 'tcx>(
|
||||
} else {
|
||||
// Always use null even if it's not the `discrfield`th
|
||||
// field; see #8506.
|
||||
Const::new(C_null(ccx.llvm_type_of(t)), t)
|
||||
Const::new(C_null(ccx.layout_of(t).llvm_type(ccx)), t)
|
||||
}
|
||||
}
|
||||
_ => bug!("trans_const_adt: cannot handle type {} repreented as {:#?}", t, l)
|
||||
|
@ -109,7 +109,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
-> LvalueRef<'tcx> {
|
||||
debug!("alloca({:?}: {:?})", name, layout);
|
||||
let tmp = bcx.alloca(
|
||||
bcx.ccx.llvm_type_of(layout.ty), name, layout.over_align(bcx.ccx));
|
||||
layout.llvm_type(bcx.ccx), name, layout.over_align(bcx.ccx));
|
||||
Self::new_sized(tmp, layout, Alignment::AbiAligned)
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
} else {
|
||||
bcx.load(self.llval, self.alignment.non_abi())
|
||||
};
|
||||
OperandValue::Immediate(base::to_immediate(bcx, llval, self.layout.ty))
|
||||
OperandValue::Immediate(base::to_immediate(bcx, llval, self.layout))
|
||||
} else {
|
||||
OperandValue::Ref(self.llval, self.alignment)
|
||||
};
|
||||
@ -223,8 +223,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
bcx.struct_gep(self.llval, self.layout.llvm_field_index(ix))
|
||||
} else {
|
||||
assert_eq!(offset, 0);
|
||||
let ty = ccx.llvm_type_of(field.ty);
|
||||
bcx.pointercast(self.llval, ty.ptr_to())
|
||||
bcx.pointercast(self.llval, field.llvm_type(ccx).ptr_to())
|
||||
},
|
||||
llextra: if ccx.shared().type_has_metadata(field.ty) {
|
||||
self.llextra
|
||||
@ -296,7 +295,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
let byte_ptr = bcx.gep(byte_ptr, &[offset]);
|
||||
|
||||
// Finally, cast back to the type expected
|
||||
let ll_fty = ccx.llvm_type_of(field.ty);
|
||||
let ll_fty = field.llvm_type(ccx);
|
||||
debug!("struct_field_ptr: Field type is {:?}", ll_fty);
|
||||
|
||||
LvalueRef {
|
||||
@ -309,7 +308,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
|
||||
/// Obtain the actual discriminant of a value.
|
||||
pub fn trans_get_discr(self, bcx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
|
||||
let cast_to = bcx.ccx.immediate_llvm_type_of(cast_to);
|
||||
let cast_to = bcx.ccx.layout_of(cast_to).immediate_llvm_type(bcx.ccx);
|
||||
match *self.layout.layout {
|
||||
layout::Layout::Univariant { .. } |
|
||||
layout::Layout::UntaggedUnion { .. } => return C_uint(cast_to, 0),
|
||||
@ -357,7 +356,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
}
|
||||
layout::Layout::NullablePointer { nndiscr, .. } => {
|
||||
let cmp = if nndiscr == 0 { llvm::IntEQ } else { llvm::IntNE };
|
||||
let zero = C_null(bcx.ccx.llvm_type_of(discr.layout.ty));
|
||||
let zero = C_null(discr.layout.llvm_type(bcx.ccx));
|
||||
bcx.intcast(bcx.icmp(cmp, lldiscr, zero), cast_to, false)
|
||||
}
|
||||
_ => bug!("{} is not an enum", self.layout.ty)
|
||||
@ -373,7 +372,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
match *self.layout.layout {
|
||||
layout::Layout::General { .. } => {
|
||||
let ptr = self.project_field(bcx, 0);
|
||||
bcx.store(C_int(bcx.ccx.llvm_type_of(ptr.layout.ty), to as i64),
|
||||
bcx.store(C_int(ptr.layout.llvm_type(bcx.ccx), to as i64),
|
||||
ptr.llval, ptr.alignment.non_abi());
|
||||
}
|
||||
layout::Layout::NullablePointer { nndiscr, .. } => {
|
||||
@ -394,7 +393,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||
base::call_memset(bcx, llptr, fill_byte, size, align, false);
|
||||
} else {
|
||||
let ptr = self.project_field(bcx, 0);
|
||||
bcx.store(C_null(bcx.ccx.llvm_type_of(ptr.layout.ty)),
|
||||
bcx.store(C_null(ptr.layout.llvm_type(bcx.ccx)),
|
||||
ptr.llval, ptr.alignment.non_abi());
|
||||
}
|
||||
}
|
||||
@ -523,7 +522,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
// Cast the lvalue pointer type to the new
|
||||
// array or slice type (*[%_; new_len]).
|
||||
subslice.llval = bcx.pointercast(subslice.llval,
|
||||
bcx.ccx.llvm_type_of(subslice.layout.ty).ptr_to());
|
||||
subslice.layout.llvm_type(bcx.ccx).ptr_to());
|
||||
|
||||
subslice
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use common::{self, CrateContext, Funclet};
|
||||
use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext};
|
||||
use monomorphize::Instance;
|
||||
use abi::{ArgAttribute, FnType};
|
||||
use type_of;
|
||||
use type_of::{self, LayoutLlvmExt};
|
||||
|
||||
use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
|
||||
use syntax::symbol::keywords;
|
||||
@ -465,7 +465,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
|
||||
ty::TyAdt(def, _) if def.is_box() => arg.layout.ty.boxed_ty(),
|
||||
_ => bug!()
|
||||
};
|
||||
let data_llty = bcx.ccx.llvm_type_of(pointee);
|
||||
let data_llty = bcx.ccx.layout_of(pointee).llvm_type(bcx.ccx);
|
||||
let meta_llty = type_of::unsized_info_ty(bcx.ccx, pointee);
|
||||
|
||||
a = bcx.pointercast(a, data_llty.ptr_to());
|
||||
|
@ -84,7 +84,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
pub fn new_zst(ccx: &CrateContext<'a, 'tcx>,
|
||||
layout: FullLayout<'tcx>) -> OperandRef<'tcx> {
|
||||
assert!(layout.is_zst());
|
||||
let llty = ccx.llvm_type_of(layout.ty);
|
||||
let llty = layout.llvm_type(ccx);
|
||||
// FIXME(eddyb) ZSTs should always be immediate, not pairs.
|
||||
// This hack only exists to unpack a constant undef pair.
|
||||
Const::new(C_undef(llty), layout.ty).to_operand(ccx)
|
||||
@ -119,7 +119,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
/// Immediate aggregate with the two values.
|
||||
pub fn pack_if_pair(mut self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
|
||||
if let OperandValue::Pair(a, b) = self.val {
|
||||
let llty = bcx.ccx.llvm_type_of(self.layout.ty);
|
||||
let llty = self.layout.llvm_type(bcx.ccx);
|
||||
debug!("Operand::pack_if_pair: packing {:?} into {:?}", self, llty);
|
||||
// Reconstruct the immediate aggregate.
|
||||
let mut llpair = C_undef(llty);
|
||||
@ -142,10 +142,10 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
debug!("Operand::unpack_if_pair: unpacking {:?}", self);
|
||||
|
||||
let a = bcx.extract_value(llval, self.layout.llvm_field_index(0));
|
||||
let a = base::to_immediate(bcx, a, self.layout.field(bcx.ccx, 0).ty);
|
||||
let a = base::to_immediate(bcx, a, self.layout.field(bcx.ccx, 0));
|
||||
|
||||
let b = bcx.extract_value(llval, self.layout.llvm_field_index(1));
|
||||
let b = base::to_immediate(bcx, b, self.layout.field(bcx.ccx, 1).ty);
|
||||
let b = base::to_immediate(bcx, b, self.layout.field(bcx.ccx, 1));
|
||||
|
||||
self.val = OperandValue::Pair(a, b);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ use common::{C_bool, C_u8, C_i32, C_u32, C_u64, C_null, C_usize, C_uint, C_big_i
|
||||
use consts;
|
||||
use monomorphize;
|
||||
use type_::Type;
|
||||
use type_of;
|
||||
use type_of::{self, LayoutLlvmExt};
|
||||
use value::Value;
|
||||
|
||||
use super::{MirContext, LocalRef};
|
||||
@ -259,7 +259,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
} else { // cast to thin-ptr
|
||||
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
|
||||
// pointer-cast of that pointer to desired pointer type.
|
||||
let llcast_ty = bcx.ccx.immediate_llvm_type_of(cast.ty);
|
||||
let llcast_ty = cast.immediate_llvm_type(bcx.ccx);
|
||||
let llval = bcx.pointercast(data_ptr, llcast_ty);
|
||||
OperandValue::Immediate(llval)
|
||||
}
|
||||
@ -272,8 +272,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
let r_t_in = CastTy::from_ty(operand.layout.ty)
|
||||
.expect("bad input type for cast");
|
||||
let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast");
|
||||
let ll_t_in = bcx.ccx.immediate_llvm_type_of(operand.layout.ty);
|
||||
let ll_t_out = bcx.ccx.immediate_llvm_type_of(cast.ty);
|
||||
let ll_t_in = operand.layout.immediate_llvm_type(bcx.ccx);
|
||||
let ll_t_out = cast.immediate_llvm_type(bcx.ccx);
|
||||
let llval = operand.immediate();
|
||||
|
||||
if let Layout::General { ref discr_range, .. } = *operand.layout.layout {
|
||||
@ -453,7 +453,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||
let llsize = C_usize(bcx.ccx, size.bytes());
|
||||
let llalign = C_usize(bcx.ccx, align.abi());
|
||||
let box_layout = bcx.ccx.layout_of(bcx.tcx().mk_box(content_ty));
|
||||
let llty_ptr = bcx.ccx.llvm_type_of(box_layout.ty);
|
||||
let llty_ptr = box_layout.llvm_type(bcx.ccx);
|
||||
|
||||
// Allocate space:
|
||||
let def_id = match bcx.tcx().lang_items().require(ExchangeMallocFnLangItem) {
|
||||
|
@ -23,9 +23,11 @@ use common;
|
||||
use declare;
|
||||
use llvm;
|
||||
use monomorphize::Instance;
|
||||
use type_of::LayoutLlvmExt;
|
||||
use rustc::hir;
|
||||
use rustc::middle::trans::{Linkage, Visibility};
|
||||
use rustc::ty::{self, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax_pos::Span;
|
||||
@ -172,7 +174,7 @@ fn predefine_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
let def_id = ccx.tcx().hir.local_def_id(node_id);
|
||||
let instance = Instance::mono(ccx.tcx(), def_id);
|
||||
let ty = common::instance_ty(ccx.tcx(), &instance);
|
||||
let llty = ccx.llvm_type_of(ty);
|
||||
let llty = ccx.layout_of(ty).llvm_type(ccx);
|
||||
|
||||
let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| {
|
||||
ccx.sess().span_fatal(ccx.tcx().hir.span(node_id),
|
||||
|
@ -21,10 +21,10 @@ pub fn fat_ptr_base_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) ->
|
||||
match ty.sty {
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: t, .. }) |
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty: t, .. }) if ccx.shared().type_has_metadata(t) => {
|
||||
ccx.llvm_type_of(t).ptr_to()
|
||||
ccx.layout_of(t).llvm_type(ccx).ptr_to()
|
||||
}
|
||||
ty::TyAdt(def, _) if def.is_box() => {
|
||||
ccx.llvm_type_of(ty.boxed_ty()).ptr_to()
|
||||
ccx.layout_of(ty.boxed_ty()).llvm_type(ccx).ptr_to()
|
||||
}
|
||||
_ => bug!("expected fat ptr ty but got {:?}", ty)
|
||||
}
|
||||
@ -53,7 +53,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
// unsized).
|
||||
cx.str_slice_type()
|
||||
} else {
|
||||
let ptr_ty = cx.llvm_type_of(ty).ptr_to();
|
||||
let ptr_ty = cx.layout_of(ty).llvm_type(cx).ptr_to();
|
||||
let info_ty = unsized_info_ty(cx, ty);
|
||||
Type::struct_(cx, &[
|
||||
Type::array(&Type::i8(cx), 0),
|
||||
@ -64,7 +64,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
], false)
|
||||
}
|
||||
} else {
|
||||
cx.llvm_type_of(ty).ptr_to()
|
||||
cx.layout_of(ty).llvm_type(cx).ptr_to()
|
||||
}
|
||||
};
|
||||
match ty.sty {
|
||||
@ -89,13 +89,15 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
layout::Int(i, _) => Type::from_integer(cx, i),
|
||||
layout::F32 => Type::f32(cx),
|
||||
layout::F64 => Type::f64(cx),
|
||||
layout::Pointer => cx.llvm_type_of(layout::Pointer.to_ty(cx.tcx()))
|
||||
layout::Pointer => {
|
||||
cx.layout_of(layout::Pointer.to_ty(cx.tcx())).llvm_type(cx)
|
||||
}
|
||||
};
|
||||
return llty;
|
||||
}
|
||||
|
||||
if let layout::Abi::Vector { .. } = layout.abi {
|
||||
return Type::vector(&cx.llvm_type_of(layout.field(cx, 0).ty),
|
||||
return Type::vector(&layout.field(cx, 0).llvm_type(cx),
|
||||
layout.fields.count() as u64);
|
||||
}
|
||||
|
||||
@ -125,7 +127,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
layout::FieldPlacement::Array { count, .. } => {
|
||||
Type::array(&cx.llvm_type_of(layout.field(cx, 0).ty), count)
|
||||
Type::array(&layout.field(cx, 0).llvm_type(cx), count)
|
||||
}
|
||||
layout::FieldPlacement::Arbitrary { .. } => {
|
||||
match name {
|
||||
@ -161,8 +163,7 @@ pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
result.push(Type::array(&Type::i8(cx), padding.bytes()));
|
||||
debug!(" padding before: {:?}", padding);
|
||||
|
||||
let llty = cx.llvm_type_of(field.ty);
|
||||
result.push(llty);
|
||||
result.push(field.llvm_type(cx));
|
||||
|
||||
if layout.is_packed() {
|
||||
assert_eq!(padding.bytes(), 0);
|
||||
@ -206,12 +207,16 @@ impl<'a, 'tcx> CrateContext<'a, 'tcx> {
|
||||
let layout = self.layout_of(ty);
|
||||
(layout.size(self), layout.align(self))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns alignment if it is different than the primitive alignment.
|
||||
pub fn over_align_of(&self, ty: Ty<'tcx>) -> Option<Align> {
|
||||
self.layout_of(ty).over_align(self)
|
||||
}
|
||||
pub trait LayoutLlvmExt<'tcx> {
|
||||
fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type;
|
||||
fn immediate_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type;
|
||||
fn over_align(&self, ccx: &CrateContext) -> Option<Align>;
|
||||
fn llvm_field_index(&self, index: usize) -> u64;
|
||||
}
|
||||
|
||||
impl<'tcx> LayoutLlvmExt<'tcx> for FullLayout<'tcx> {
|
||||
/// Get the LLVM type corresponding to a Rust type, i.e. `rustc::ty::Ty`.
|
||||
/// The pointee type of the pointer in `LvalueRef` is always this type.
|
||||
/// For sized types, it is also the right LLVM type for an `alloca`
|
||||
@ -223,56 +228,45 @@ impl<'a, 'tcx> CrateContext<'a, 'tcx> {
|
||||
/// with the inner-most trailing unsized field using the "minimal unit"
|
||||
/// of that field's type - this is useful for taking the address of
|
||||
/// that field and ensuring the struct has the right alignment.
|
||||
pub fn llvm_type_of(&self, ty: Ty<'tcx>) -> Type {
|
||||
fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
|
||||
// Check the cache.
|
||||
if let Some(&llty) = self.lltypes().borrow().get(&ty) {
|
||||
if let Some(&llty) = ccx.lltypes().borrow().get(&self.ty) {
|
||||
return llty;
|
||||
}
|
||||
|
||||
debug!("type_of {:?}", ty);
|
||||
debug!("llvm_type({:#?})", self);
|
||||
|
||||
assert!(!ty.has_escaping_regions(), "{:?} has escaping regions", ty);
|
||||
assert!(!self.ty.has_escaping_regions(), "{:?} has escaping regions", self.ty);
|
||||
|
||||
// Make sure lifetimes are erased, to avoid generating distinct LLVM
|
||||
// types for Rust types that only differ in the choice of lifetimes.
|
||||
let normal_ty = self.tcx().erase_regions(&ty);
|
||||
|
||||
if ty != normal_ty {
|
||||
let llty = self.llvm_type_of(normal_ty);
|
||||
debug!("--> normalized {:?} to {:?} llty={:?}", ty, normal_ty, llty);
|
||||
self.lltypes().borrow_mut().insert(ty, llty);
|
||||
return llty;
|
||||
}
|
||||
let normal_ty = ccx.tcx().erase_regions(&self.ty);
|
||||
|
||||
let mut defer = None;
|
||||
let llty = uncached_llvm_type(self, ty, &mut defer);
|
||||
let llty = if self.ty != normal_ty {
|
||||
ccx.layout_of(normal_ty).llvm_type(ccx)
|
||||
} else {
|
||||
uncached_llvm_type(ccx, self.ty, &mut defer)
|
||||
};
|
||||
debug!("--> mapped {:#?} to llty={:?}", self, llty);
|
||||
|
||||
debug!("--> mapped ty={:?} to llty={:?}", ty, llty);
|
||||
|
||||
self.lltypes().borrow_mut().insert(ty, llty);
|
||||
ccx.lltypes().borrow_mut().insert(self.ty, llty);
|
||||
|
||||
if let Some((mut llty, layout)) = defer {
|
||||
llty.set_struct_body(&struct_llfields(self, layout), layout.is_packed())
|
||||
llty.set_struct_body(&struct_llfields(ccx, layout), layout.is_packed())
|
||||
}
|
||||
|
||||
llty
|
||||
}
|
||||
|
||||
pub fn immediate_llvm_type_of(&self, ty: Ty<'tcx>) -> Type {
|
||||
if ty.is_bool() {
|
||||
Type::i1(self)
|
||||
fn immediate_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
|
||||
if let layout::Abi::Scalar(layout::Int(layout::I1, _)) = self.abi {
|
||||
Type::i1(ccx)
|
||||
} else {
|
||||
self.llvm_type_of(ty)
|
||||
self.llvm_type(ccx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LayoutLlvmExt {
|
||||
fn over_align(&self, ccx: &CrateContext) -> Option<Align>;
|
||||
fn llvm_field_index(&self, index: usize) -> u64;
|
||||
}
|
||||
|
||||
impl<'tcx> LayoutLlvmExt for FullLayout<'tcx> {
|
||||
fn over_align(&self, ccx: &CrateContext) -> Option<Align> {
|
||||
let align = self.align(ccx);
|
||||
let primitive_align = self.primitive_align(ccx);
|
||||
|
Loading…
Reference in New Issue
Block a user