about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAustin Hicks <camlorn@camlorn.net>2016-09-24 16:06:38 -0400
committerAustin Hicks <camlorn@camlorn.net>2016-09-24 18:21:12 -0400
commit4038189688ce2705d41bec97238715aa17f44c1d (patch)
tree375389db08a4f92d94be32601f0b1e4f4ecf9e07
parentf16068e577a916122ff1f24719aad2b80e40c975 (diff)
downloadrust-4038189688ce2705d41bec97238715aa17f44c1d.tar.gz
rust-4038189688ce2705d41bec97238715aa17f44c1d.zip
Optimize struct_field_ptr
-rw-r--r--src/librustc/ty/layout.rs9
-rw-r--r--src/librustc_trans/adt.rs72
-rw-r--r--src/librustc_trans/context.rs7
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 @@ impl<'a, 'gcx, 'tcx> Struct {
         }
         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 llvm::{ValueRef, True, IntEQ, IntNE};
 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
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::hir::def_id::DefId;
 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 @@ impl<'tcx> LocalCrateContext<'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 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &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
     }