rustc_trans: query LLVM types from a layout instead of a Ty.

This commit is contained in:
Eduard-Mihai Burtescu 2017-09-20 23:07:47 +03:00
parent 1477119344
commit 3fd6b00082
16 changed files with 114 additions and 116 deletions

View File

@ -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);

View File

@ -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() {

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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 {

View File

@ -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)

View File

@ -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);

View File

@ -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,

View File

@ -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)

View File

@ -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
}

View File

@ -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());

View File

@ -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);
}

View File

@ -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) {

View File

@ -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),

View File

@ -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);