]> git.lizzy.rs Git - rust.git/commitdiff
introduce `base_and_len` fns for element length
authorDaniel Micay <danielmicay@gmail.com>
Wed, 16 Oct 2013 16:04:51 +0000 (12:04 -0400)
committerDaniel Micay <danielmicay@gmail.com>
Wed, 16 Oct 2013 16:28:25 +0000 (12:28 -0400)
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/datum.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/tvec.rs

index dc07852ad9130d8f2f0785ffd375af1cd2632a8b..dbcfb4eebbffae8eaaee7df796e0315691296c98 100644 (file)
@@ -1025,7 +1025,7 @@ fn extract_vec_elems(bcx: @mut Block,
                       -> ExtractedBlock {
     let _icx = push_ctxt("match::extract_vec_elems");
     let vec_datum = match_datum(bcx, val, pat_id);
-    let (bcx, base, len) = vec_datum.get_vec_base_and_byte_len(bcx, pat_span, pat_id, 0);
+    let (bcx, base, len) = vec_datum.get_vec_base_and_len(bcx, pat_span, pat_id, 0);
     let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
 
     let mut elems = do vec::from_fn(elem_count) |i| {
@@ -1042,13 +1042,9 @@ fn extract_vec_elems(bcx: @mut Block,
     };
     if slice.is_some() {
         let n = slice.unwrap();
-        let slice_offset = Mul(bcx, vt.llunit_size,
-            C_int(bcx.ccx(), n as int)
-        );
-        let slice_begin = tvec::pointer_add(bcx, base, slice_offset);
-        let slice_len_offset = Mul(bcx, vt.llunit_size,
-            C_int(bcx.ccx(), (elem_count - 1u) as int)
-        );
+        let slice_byte_offset = Mul(bcx, vt.llunit_size, C_uint(bcx.ccx(), n));
+        let slice_begin = tvec::pointer_add_byte(bcx, base, slice_byte_offset);
+        let slice_len_offset = C_uint(bcx.ccx(), elem_count - 1u);
         let slice_len = Sub(bcx, len, slice_len_offset);
         let slice_ty = ty::mk_evec(bcx.tcx(),
             ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable},
@@ -1058,9 +1054,7 @@ fn extract_vec_elems(bcx: @mut Block,
         Store(bcx, slice_begin,
             GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])
         );
-        Store(bcx, UDiv(bcx, slice_len, vt.llunit_size),
-            GEPi(bcx, scratch.val, [0u, abi::slice_elt_len])
-        );
+        Store(bcx, slice_len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
         elems[n] = scratch.val;
         scratch.add_clean(bcx);
     }
@@ -1646,8 +1640,8 @@ fn compile_submatch_continue(mut bcx: @mut Block,
             vec_len(*) => {
                 let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
                 let unboxed = load_if_immediate(bcx, val, vt.vec_ty);
-                let (_, len) = tvec::get_base_and_byte_len(bcx, unboxed, vt.vec_ty);
-                test_val = SDiv(bcx, len, vt.llunit_size);
+                let (_, len) = tvec::get_base_and_len(bcx, unboxed, vt.vec_ty);
+                test_val = len;
                 kind = compare_vec_len;
             }
         }
index 3055c1e64fcdd187d5fa3ec9d26d89088d06d4ab..105cb6e5606db60772d51a4fc2880f8b9dc8a853 100644 (file)
@@ -305,7 +305,7 @@ pub fn trans_fail_expr(bcx: @mut Block,
                 bcx, expr::trans_to_datum(bcx, arg_expr));
 
             if ty::type_is_str(arg_datum.ty) {
-                let (lldata, _) = arg_datum.get_vec_base_and_byte_len_no_root(bcx);
+                let (lldata, _) = arg_datum.get_vec_base_and_len_no_root(bcx);
                 return trans_fail_value(bcx, sp_opt, lldata);
             } else if bcx.unreachable || ty::type_is_bot(arg_datum.ty) {
                 return bcx;
index 34f1a6fa2a78a1507f1adb7d5213026b17dedd76..6411283b79d0e089a740723977fc27c8c43f21df 100644 (file)
@@ -794,6 +794,30 @@ pub fn get_vec_base_and_byte_len_no_root(&self, bcx: @mut Block)
         tvec::get_base_and_byte_len(bcx, llval, self.ty)
     }
 
+    pub fn get_vec_base_and_len(&self,
+                                     mut bcx: @mut Block,
+                                     span: Span,
+                                     expr_id: ast::NodeId,
+                                     derefs: uint)
+                                     -> (@mut Block, ValueRef, ValueRef) {
+        //! Converts a vector into the slice pair. Performs rooting
+        //! and write guards checks.
+
+        // only imp't for @[] and @str, but harmless
+        bcx = write_guard::root_and_write_guard(self, bcx, span, expr_id, derefs);
+        let (base, len) = self.get_vec_base_and_len_no_root(bcx);
+        (bcx, base, len)
+    }
+
+    pub fn get_vec_base_and_len_no_root(&self, bcx: @mut Block)
+                                             -> (ValueRef, ValueRef) {
+        //! Converts a vector into the slice pair. Des not root
+        //! nor perform write guard checks.
+
+        let llval = self.to_appropriate_llval(bcx);
+        tvec::get_base_and_len(bcx, llval, self.ty)
+    }
+
     pub fn root_and_write_guard(&self,
                                 bcx: @mut Block,
                                 span: Span,
index 81ab3b5f2ec867c1251103f8914d6e17bbb9cb4a..48d3e3f7c58b893d4c4f62ae805ea11ecd7b629f 100644 (file)
@@ -265,7 +265,7 @@ fn auto_slice(bcx: @mut Block,
         let unit_ty = ty::sequence_element_type(tcx, datum.ty);
 
         let (bcx, base, len) =
-            datum.get_vec_base_and_byte_len(bcx, expr.span, expr.id, autoderefs+1);
+            datum.get_vec_base_and_len(bcx, expr.span, expr.id, autoderefs+1);
 
         // this type may have a different region/mutability than the
         // real one, but it will have the same runtime representation
@@ -275,11 +275,8 @@ fn auto_slice(bcx: @mut Block,
 
         let scratch = scratch_datum(bcx, slice_ty, "__adjust", false);
 
-        let vt = tvec::vec_types(bcx, datum.ty);
-        let unscaled_len = UDiv(bcx, len, vt.llunit_size);
-
         Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
-        Store(bcx, unscaled_len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
+        Store(bcx, len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
         DatumBlock {bcx: bcx, datum: scratch}
     }
 
@@ -978,17 +975,14 @@ fn trans_index(bcx: @mut Block,
         base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
 
         let (bcx, base, len) =
-            base_datum.get_vec_base_and_byte_len(bcx, index_expr.span,
-                                                 index_expr.id, 0);
+            base_datum.get_vec_base_and_len(bcx, index_expr.span, index_expr.id, 0);
 
         debug2!("trans_index: base {}", bcx.val_to_str(base));
         debug2!("trans_index: len {}", bcx.val_to_str(len));
 
-        let unscaled_len = UDiv(bcx, len, vt.llunit_size);
-        let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, unscaled_len);
+        let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, len);
         let bcx = do with_cond(bcx, bounds_check) |bcx| {
-            controlflow::trans_fail_bounds_check(bcx, index_expr.span,
-                                                 ix_val, unscaled_len)
+            controlflow::trans_fail_bounds_check(bcx, index_expr.span, ix_val, len)
         };
         let elt = InBoundsGEP(bcx, base, [ix_val]);
         let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
index eab642ccb91de7a381dfb2084ed534aa0987ff44..bde98eff41ce777a45d1edce4a05fcf29bd545e0 100644 (file)
@@ -77,8 +77,8 @@ pub fn get_dataptr(bcx: @mut Block, vptr: ValueRef) -> ValueRef {
     GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u])
 }
 
-pub fn pointer_add(bcx: @mut Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
-    let _icx = push_ctxt("tvec::pointer_add");
+pub fn pointer_add_byte(bcx: @mut Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
+    let _icx = push_ctxt("tvec::pointer_add_byte");
     let old_ty = val_ty(ptr);
     let bptr = PointerCast(bcx, ptr, Type::i8p());
     return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
@@ -501,8 +501,7 @@ pub fn elements_required(bcx: @mut Block, content_expr: &ast::Expr) -> uint {
     }
 }
 
-pub fn get_base_and_byte_len(bcx: @mut Block,
-                        llval: ValueRef,
+pub fn get_base_and_byte_len(bcx: @mut Block, llval: ValueRef,
                         vec_ty: ty::t) -> (ValueRef, ValueRef) {
     //!
     //
@@ -539,6 +538,40 @@ pub fn get_base_and_byte_len(bcx: @mut Block,
     }
 }
 
+pub fn get_base_and_len(bcx: @mut Block, llval: ValueRef, vec_ty: ty::t) -> (ValueRef, ValueRef) {
+    //!
+    //
+    // Converts a vector into the slice pair.  The vector should be stored in
+    // `llval` which should be either immediate or by-ref as appropriate for
+    // the vector type.  If you have a datum, you would probably prefer to
+    // call `Datum::get_base_and_len()` which will handle any conversions for
+    // you.
+
+    let ccx = bcx.ccx();
+    let vt = vec_types(bcx, vec_ty);
+
+    let vstore = match ty::get(vt.vec_ty).sty {
+      ty::ty_estr(vst) | ty::ty_evec(_, vst) => vst,
+      _ => ty::vstore_uniq
+    };
+
+    match vstore {
+        ty::vstore_fixed(n) => {
+            let base = GEPi(bcx, llval, [0u, 0u]);
+            (base, C_uint(ccx, n))
+        }
+        ty::vstore_slice(_) => {
+            let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base]));
+            let count = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
+            (base, count)
+        }
+        ty::vstore_uniq | ty::vstore_box => {
+            let body = get_bodyptr(bcx, llval, vec_ty);
+            (get_dataptr(bcx, body), UDiv(bcx, get_fill(bcx, body), vt.llunit_size))
+        }
+    }
+}
+
 pub type iter_vec_block<'self> = &'self fn(@mut Block, ValueRef, ty::t) -> @mut Block;
 
 pub fn iter_vec_raw(bcx: @mut Block, data_ptr: ValueRef, vec_ty: ty::t,
@@ -551,7 +584,7 @@ pub fn iter_vec_raw(bcx: @mut Block, data_ptr: ValueRef, vec_ty: ty::t,
     // FIXME (#3729): Optimize this when the size of the unit type is
     // statically known to not use pointer casts, which tend to confuse
     // LLVM.
-    let data_end_ptr = pointer_add(bcx, data_ptr, fill);
+    let data_end_ptr = pointer_add_byte(bcx, data_ptr, fill);
 
     // Now perform the iteration.
     let header_bcx = base::sub_block(bcx, "iter_vec_loop_header");