Optimize struct_field_ptr

This commit is contained in:
Austin Hicks 2016-09-24 16:06:38 -04:00
parent f16068e577
commit 4038189688
3 changed files with 11 additions and 77 deletions

View File

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

View File

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

View File

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