Optimize struct_field_ptr
This commit is contained in:
parent
f16068e577
commit
4038189688
@ -650,6 +650,15 @@ pub fn non_zero_field_path<I>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn offset_of_field(&self, index: usize) -> Size {
|
||||
assert!(index < self.offset_after_field.len());
|
||||
if index == 0 {
|
||||
Size::from_bytes(0)
|
||||
} else {
|
||||
self.offset_after_field[index-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An untagged union.
|
||||
|
@ -41,7 +41,6 @@
|
||||
//! used unboxed and any field can have pointers (including mutable)
|
||||
//! taken to it, implementing them for Rust seems difficult.
|
||||
|
||||
pub use self::Repr::*;
|
||||
use super::Disr;
|
||||
|
||||
use std;
|
||||
@ -50,7 +49,6 @@
|
||||
use rustc::ty::layout;
|
||||
use rustc::ty::{self, Ty, AdtKind};
|
||||
use syntax::attr;
|
||||
use syntax::attr::IntType;
|
||||
use build::*;
|
||||
use common::*;
|
||||
use debuginfo::DebugLoc;
|
||||
@ -70,66 +68,6 @@ pub enum BranchKind {
|
||||
|
||||
type Hint = attr::ReprAttr;
|
||||
|
||||
/// Representations.
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub enum Repr<'tcx> {
|
||||
/// C-like enums; basically an int.
|
||||
CEnum(IntType, Disr, Disr), // discriminant range (signedness based on the IntType)
|
||||
/// Single-case variants, and structs/tuples/records.
|
||||
Univariant(Struct<'tcx>),
|
||||
/// Untagged unions.
|
||||
UntaggedUnion(Union<'tcx>),
|
||||
/// General-case enums: for each case there is a struct, and they
|
||||
/// all start with a field for the discriminant.
|
||||
General(IntType, Vec<Struct<'tcx>>),
|
||||
/// Two cases distinguished by a nullable pointer: the case with discriminant
|
||||
/// `nndiscr` must have single field which is known to be nonnull due to its type.
|
||||
/// The other case is known to be zero sized. Hence we represent the enum
|
||||
/// as simply a nullable pointer: if not null it indicates the `nndiscr` variant,
|
||||
/// otherwise it indicates the other case.
|
||||
RawNullablePointer {
|
||||
nndiscr: Disr,
|
||||
nnty: Ty<'tcx>,
|
||||
nullfields: Vec<Ty<'tcx>>
|
||||
},
|
||||
/// Two cases distinguished by a nullable pointer: the case with discriminant
|
||||
/// `nndiscr` is represented by the struct `nonnull`, where the `discrfield`th
|
||||
/// field is known to be nonnull due to its type; if that field is null, then
|
||||
/// it represents the other case, which is inhabited by at most one value
|
||||
/// (and all other fields are undefined/unused).
|
||||
///
|
||||
/// For example, `std::option::Option` instantiated at a safe pointer type
|
||||
/// is represented such that `None` is a null pointer and `Some` is the
|
||||
/// identity function.
|
||||
StructWrappedNullablePointer {
|
||||
nonnull: Struct<'tcx>,
|
||||
nndiscr: Disr,
|
||||
discrfield: DiscrField,
|
||||
nullfields: Vec<Ty<'tcx>>,
|
||||
}
|
||||
}
|
||||
|
||||
/// For structs, and struct-like parts of anything fancier.
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub struct Struct<'tcx> {
|
||||
// If the struct is DST, then the size and alignment do not take into
|
||||
// account the unsized fields of the struct.
|
||||
pub size: u64,
|
||||
pub align: u32,
|
||||
pub sized: bool,
|
||||
pub packed: bool,
|
||||
pub fields: Vec<Ty<'tcx>>,
|
||||
}
|
||||
|
||||
/// For untagged unions.
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
pub struct Union<'tcx> {
|
||||
pub min_size: u64,
|
||||
pub align: u32,
|
||||
pub packed: bool,
|
||||
pub fields: Vec<Ty<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct MaybeSizedValue {
|
||||
pub value: ValueRef,
|
||||
@ -696,14 +634,8 @@ fn struct_field_ptr<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
|
||||
|
||||
let meta = val.meta;
|
||||
|
||||
// Calculate the unaligned offset of the unsized field.
|
||||
let mut offset = 0;
|
||||
for &ty in &fields[0..ix] {
|
||||
let llty = type_of::sizing_type_of(ccx, ty);
|
||||
let type_align = type_of::align_of(ccx, ty);
|
||||
offset = roundup(offset, type_align);
|
||||
offset += machine::llsize_of_alloc(ccx, llty);
|
||||
}
|
||||
|
||||
let offset = st.offset_of_field(ix).bytes();
|
||||
let unaligned_offset = C_uint(bcx.ccx(), offset);
|
||||
|
||||
// Get the alignment of the field
|
||||
|
@ -17,7 +17,6 @@
|
||||
use rustc::traits;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::mir::repr as mir;
|
||||
use adt;
|
||||
use base;
|
||||
use builder::Builder;
|
||||
use common::BuilderRef_res;
|
||||
@ -142,7 +141,6 @@ pub struct LocalCrateContext<'tcx> {
|
||||
|
||||
lltypes: RefCell<FnvHashMap<Ty<'tcx>, Type>>,
|
||||
llsizingtypes: RefCell<FnvHashMap<Ty<'tcx>, Type>>,
|
||||
adt_reprs: RefCell<FnvHashMap<Ty<'tcx>, Rc<adt::Repr<'tcx>>>>,
|
||||
type_hashcodes: RefCell<FnvHashMap<Ty<'tcx>, String>>,
|
||||
int_type: Type,
|
||||
opaque_vec_type: Type,
|
||||
@ -677,7 +675,6 @@ fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
|
||||
statics_to_rauw: RefCell::new(Vec::new()),
|
||||
lltypes: RefCell::new(FnvHashMap()),
|
||||
llsizingtypes: RefCell::new(FnvHashMap()),
|
||||
adt_reprs: RefCell::new(FnvHashMap()),
|
||||
type_hashcodes: RefCell::new(FnvHashMap()),
|
||||
int_type: Type::from_ref(ptr::null_mut()),
|
||||
opaque_vec_type: Type::from_ref(ptr::null_mut()),
|
||||
@ -918,10 +915,6 @@ pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell<FnvHashMap<Ty<'tcx>, Type>> {
|
||||
&self.local().llsizingtypes
|
||||
}
|
||||
|
||||
pub fn adt_reprs<'a>(&'a self) -> &'a RefCell<FnvHashMap<Ty<'tcx>, Rc<adt::Repr<'tcx>>>> {
|
||||
&self.local().adt_reprs
|
||||
}
|
||||
|
||||
pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell<Sha256> {
|
||||
&self.shared.symbol_hasher
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user