From 4038189688ce2705d41bec97238715aa17f44c1d Mon Sep 17 00:00:00 2001 From: Austin Hicks Date: Sat, 24 Sep 2016 16:06:38 -0400 Subject: [PATCH] Optimize struct_field_ptr --- src/librustc/ty/layout.rs | 9 +++++ src/librustc_trans/adt.rs | 72 +---------------------------------- src/librustc_trans/context.rs | 7 ---- 3 files changed, 11 insertions(+), 77 deletions(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index c8bcda8c530..9bc1c1bc960 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -650,6 +650,15 @@ pub fn non_zero_field_path(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. diff --git a/src/librustc_trans/adt.rs b/src/librustc_trans/adt.rs index e3b15c8e2b9..c7528c0cf69 100644 --- a/src/librustc_trans/adt.rs +++ b/src/librustc_trans/adt.rs @@ -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>), - /// 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> - }, - /// 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>, - } -} - -/// 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>, -} - -/// For untagged unions. -#[derive(Eq, PartialEq, Debug)] -pub struct Union<'tcx> { - pub min_size: u64, - pub align: u32, - pub packed: bool, - pub fields: Vec>, -} - #[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 diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index f7b89f6f1bb..1b67516a9e6 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -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, Type>>, llsizingtypes: RefCell, Type>>, - adt_reprs: RefCell, Rc>>>, type_hashcodes: RefCell, 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, Type>> { &self.local().llsizingtypes } - pub fn adt_reprs<'a>(&'a self) -> &'a RefCell, Rc>>> { - &self.local().adt_reprs - } - pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell { &self.shared.symbol_hasher }