Skip to content

Commit bd7610f

Browse files
committed
introduce base_and_len fns for element length
1 parent ef3ec1f commit bd7610f

File tree

5 files changed

+75
-30
lines changed

5 files changed

+75
-30
lines changed

src/librustc/middle/trans/_match.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ fn extract_vec_elems(bcx: @mut Block,
10251025
-> ExtractedBlock {
10261026
let _icx = push_ctxt("match::extract_vec_elems");
10271027
let vec_datum = match_datum(bcx, val, pat_id);
1028-
let (bcx, base, len) = vec_datum.get_vec_base_and_byte_len(bcx, pat_span, pat_id, 0);
1028+
let (bcx, base, len) = vec_datum.get_vec_base_and_len(bcx, pat_span, pat_id, 0);
10291029
let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
10301030

10311031
let mut elems = do vec::from_fn(elem_count) |i| {
@@ -1042,13 +1042,9 @@ fn extract_vec_elems(bcx: @mut Block,
10421042
};
10431043
if slice.is_some() {
10441044
let n = slice.unwrap();
1045-
let slice_offset = Mul(bcx, vt.llunit_size,
1046-
C_int(bcx.ccx(), n as int)
1047-
);
1048-
let slice_begin = tvec::pointer_add(bcx, base, slice_offset);
1049-
let slice_len_offset = Mul(bcx, vt.llunit_size,
1050-
C_int(bcx.ccx(), (elem_count - 1u) as int)
1051-
);
1045+
let slice_byte_offset = Mul(bcx, vt.llunit_size, C_uint(bcx.ccx(), n));
1046+
let slice_begin = tvec::pointer_add_byte(bcx, base, slice_byte_offset);
1047+
let slice_len_offset = C_uint(bcx.ccx(), elem_count - 1u);
10521048
let slice_len = Sub(bcx, len, slice_len_offset);
10531049
let slice_ty = ty::mk_evec(bcx.tcx(),
10541050
ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable},
@@ -1058,9 +1054,7 @@ fn extract_vec_elems(bcx: @mut Block,
10581054
Store(bcx, slice_begin,
10591055
GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])
10601056
);
1061-
Store(bcx, UDiv(bcx, slice_len, vt.llunit_size),
1062-
GEPi(bcx, scratch.val, [0u, abi::slice_elt_len])
1063-
);
1057+
Store(bcx, slice_len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
10641058
elems[n] = scratch.val;
10651059
scratch.add_clean(bcx);
10661060
}
@@ -1646,8 +1640,8 @@ fn compile_submatch_continue(mut bcx: @mut Block,
16461640
vec_len(*) => {
16471641
let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
16481642
let unboxed = load_if_immediate(bcx, val, vt.vec_ty);
1649-
let (_, len) = tvec::get_base_and_byte_len(bcx, unboxed, vt.vec_ty);
1650-
test_val = SDiv(bcx, len, vt.llunit_size);
1643+
let (_, len) = tvec::get_base_and_len(bcx, unboxed, vt.vec_ty);
1644+
test_val = len;
16511645
kind = compare_vec_len;
16521646
}
16531647
}

src/librustc/middle/trans/controlflow.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ pub fn trans_fail_expr(bcx: @mut Block,
305305
bcx, expr::trans_to_datum(bcx, arg_expr));
306306

307307
if ty::type_is_str(arg_datum.ty) {
308-
let (lldata, _) = arg_datum.get_vec_base_and_byte_len_no_root(bcx);
308+
let (lldata, _) = arg_datum.get_vec_base_and_len_no_root(bcx);
309309
return trans_fail_value(bcx, sp_opt, lldata);
310310
} else if bcx.unreachable || ty::type_is_bot(arg_datum.ty) {
311311
return bcx;

src/librustc/middle/trans/datum.rs

+24
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,30 @@ impl Datum {
794794
tvec::get_base_and_byte_len(bcx, llval, self.ty)
795795
}
796796

797+
pub fn get_vec_base_and_len(&self,
798+
mut bcx: @mut Block,
799+
span: Span,
800+
expr_id: ast::NodeId,
801+
derefs: uint)
802+
-> (@mut Block, ValueRef, ValueRef) {
803+
//! Converts a vector into the slice pair. Performs rooting
804+
//! and write guards checks.
805+
806+
// only imp't for @[] and @str, but harmless
807+
bcx = write_guard::root_and_write_guard(self, bcx, span, expr_id, derefs);
808+
let (base, len) = self.get_vec_base_and_len_no_root(bcx);
809+
(bcx, base, len)
810+
}
811+
812+
pub fn get_vec_base_and_len_no_root(&self, bcx: @mut Block)
813+
-> (ValueRef, ValueRef) {
814+
//! Converts a vector into the slice pair. Des not root
815+
//! nor perform write guard checks.
816+
817+
let llval = self.to_appropriate_llval(bcx);
818+
tvec::get_base_and_len(bcx, llval, self.ty)
819+
}
820+
797821
pub fn root_and_write_guard(&self,
798822
bcx: @mut Block,
799823
span: Span,

src/librustc/middle/trans/expr.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ pub fn trans_to_datum(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
265265
let unit_ty = ty::sequence_element_type(tcx, datum.ty);
266266

267267
let (bcx, base, len) =
268-
datum.get_vec_base_and_byte_len(bcx, expr.span, expr.id, autoderefs+1);
268+
datum.get_vec_base_and_len(bcx, expr.span, expr.id, autoderefs+1);
269269

270270
// this type may have a different region/mutability than the
271271
// real one, but it will have the same runtime representation
@@ -275,11 +275,8 @@ pub fn trans_to_datum(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
275275

276276
let scratch = scratch_datum(bcx, slice_ty, "__adjust", false);
277277

278-
let vt = tvec::vec_types(bcx, datum.ty);
279-
let unscaled_len = UDiv(bcx, len, vt.llunit_size);
280-
281278
Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
282-
Store(bcx, unscaled_len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
279+
Store(bcx, len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
283280
DatumBlock {bcx: bcx, datum: scratch}
284281
}
285282

@@ -978,17 +975,14 @@ fn trans_lvalue_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
978975
base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
979976

980977
let (bcx, base, len) =
981-
base_datum.get_vec_base_and_byte_len(bcx, index_expr.span,
982-
index_expr.id, 0);
978+
base_datum.get_vec_base_and_len(bcx, index_expr.span, index_expr.id, 0);
983979

984980
debug2!("trans_index: base {}", bcx.val_to_str(base));
985981
debug2!("trans_index: len {}", bcx.val_to_str(len));
986982

987-
let unscaled_len = UDiv(bcx, len, vt.llunit_size);
988-
let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, unscaled_len);
983+
let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, len);
989984
let bcx = do with_cond(bcx, bounds_check) |bcx| {
990-
controlflow::trans_fail_bounds_check(bcx, index_expr.span,
991-
ix_val, unscaled_len)
985+
controlflow::trans_fail_bounds_check(bcx, index_expr.span, ix_val, len)
992986
};
993987
let elt = InBoundsGEP(bcx, base, [ix_val]);
994988
let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());

src/librustc/middle/trans/tvec.rs

+38-5
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ pub fn get_dataptr(bcx: @mut Block, vptr: ValueRef) -> ValueRef {
7777
GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u])
7878
}
7979

80-
pub fn pointer_add(bcx: @mut Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
81-
let _icx = push_ctxt("tvec::pointer_add");
80+
pub fn pointer_add_byte(bcx: @mut Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
81+
let _icx = push_ctxt("tvec::pointer_add_byte");
8282
let old_ty = val_ty(ptr);
8383
let bptr = PointerCast(bcx, ptr, Type::i8p());
8484
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 {
501501
}
502502
}
503503

504-
pub fn get_base_and_byte_len(bcx: @mut Block,
505-
llval: ValueRef,
504+
pub fn get_base_and_byte_len(bcx: @mut Block, llval: ValueRef,
506505
vec_ty: ty::t) -> (ValueRef, ValueRef) {
507506
//!
508507
//
@@ -539,6 +538,40 @@ pub fn get_base_and_byte_len(bcx: @mut Block,
539538
}
540539
}
541540

541+
pub fn get_base_and_len(bcx: @mut Block, llval: ValueRef, vec_ty: ty::t) -> (ValueRef, ValueRef) {
542+
//!
543+
//
544+
// Converts a vector into the slice pair. The vector should be stored in
545+
// `llval` which should be either immediate or by-ref as appropriate for
546+
// the vector type. If you have a datum, you would probably prefer to
547+
// call `Datum::get_base_and_len()` which will handle any conversions for
548+
// you.
549+
550+
let ccx = bcx.ccx();
551+
let vt = vec_types(bcx, vec_ty);
552+
553+
let vstore = match ty::get(vt.vec_ty).sty {
554+
ty::ty_estr(vst) | ty::ty_evec(_, vst) => vst,
555+
_ => ty::vstore_uniq
556+
};
557+
558+
match vstore {
559+
ty::vstore_fixed(n) => {
560+
let base = GEPi(bcx, llval, [0u, 0u]);
561+
(base, C_uint(ccx, n))
562+
}
563+
ty::vstore_slice(_) => {
564+
let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base]));
565+
let count = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
566+
(base, count)
567+
}
568+
ty::vstore_uniq | ty::vstore_box => {
569+
let body = get_bodyptr(bcx, llval, vec_ty);
570+
(get_dataptr(bcx, body), UDiv(bcx, get_fill(bcx, body), vt.llunit_size))
571+
}
572+
}
573+
}
574+
542575
pub type iter_vec_block<'self> = &'self fn(@mut Block, ValueRef, ty::t) -> @mut Block;
543576

544577
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,
551584
// FIXME (#3729): Optimize this when the size of the unit type is
552585
// statically known to not use pointer casts, which tend to confuse
553586
// LLVM.
554-
let data_end_ptr = pointer_add(bcx, data_ptr, fill);
587+
let data_end_ptr = pointer_add_byte(bcx, data_ptr, fill);
555588

556589
// Now perform the iteration.
557590
let header_bcx = base::sub_block(bcx, "iter_vec_loop_header");

0 commit comments

Comments
 (0)